Skip to content

Bug 647080: [28.x] Fix: migrating a document attachment deletes shared Tenant Media - #10310

Merged
Jesper Schulz-Wedde (JesperSchulz) merged 1 commit into
releases/28.xfrom
bugs/647080-28xBackportOf646505
Aug 20, 2026
Merged

Bug 647080: [28.x] Fix: migrating a document attachment deletes shared Tenant Media#10310
Jesper Schulz-Wedde (JesperSchulz) merged 1 commit into
releases/28.xfrom
bugs/647080-28xBackportOf646505

Conversation

@JesperSchulz

@JesperSchulz Jesper Schulz-Wedde (JesperSchulz) commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Backport of #10055 to releases/28.x for the September release (28.5).

DA External Storage Impl.DeleteFromInternalStorage deleted the Tenant Media row unconditionally after moving an attachment to external storage. Tenant Media is shared storage: Document Attachment Mgmt.CopyAttachments copies the media reference rather than the bytes, so Vendor → Purchase Header → Purch. Inv. Header attachments all end up referencing a single row. Deleting that row on behalf of one attachment destroyed the content of every attachment copied from it.

Those attachments were then skipped silently by UploadToExternalStorage — the HasValue() guard sits above LogFeatureUsed(), so no telemetry was emitted — leaving Stored Externally = false, a blank External File Path and no internal content. Opening one raises Tenant Media does not exist. ID='{00000000-0000-0000-0000-000000000000}' from GetAsTempBlob.

On a production tenant migrating 5,226 attachments in one company, 4,810 uploaded successfully and 416 were silently skipped with their content destroyed.

The fix only deletes the Tenant Media row when no other Document Attachment references it, index-backed by the existing key(Key2; "Document Reference ID") on table 1173.

Work Item(s)

Fixes AB#647080 (backport of AB#646505)

Cherry-pick

Cherry-pick of 473bb07 (-x). The AL change is byte-identical to the change merged to main (2 files, 155 insertions, 7 deletions).

One deliberate omission. The original PR also registered the External Storage - Document Attachments test app in the build, via build/groups.json and 24 × build/projects/Apps <CC>/.AL-Go/settings.json. Those files do not exist on releases/28.x, which still uses the earlier build layout:

  • there is no build/groups.json on this branch (and no equivalent grouping file — AllExtensions appears nowhere on releases/28.x);
  • build/projects/Apps (W1)/.AL-Go/settings.json declares testFolders with wildcards (../../../src/Apps/W1/*/Test), which already matches src/Apps/W1/External Storage - Document Attachments/Test.

So the test app is picked up automatically here and no registration change is needed.

Validation

Tests in DA Ext. Storage Impl. Tests:

Test Asserts
DeleteFromInternalKeepsMediaSharedWithCopiedAttachment Shared Tenant Media survives; the copy keeps its content
DeleteFromInternalRemovesMediaWhenNotShared Space is still reclaimed when the attachment is the sole owner
UploadSucceedsForCopiedAttachmentAfterSourceIsMigrated After the source is migrated, the copy still uploads and gets its own external file

The first and third fail before the fix and pass after; the middle one passes both before and after, proving the fix does not stop reclaiming database space.

)

Backport to releases/28.x of microsoft/BCApps PR #10055.

DA External Storage Impl.DeleteFromInternalStorage deleted the Tenant Media
row unconditionally after moving an attachment to external storage. Tenant
Media is shared storage: Document Attachment Mgmt.CopyAttachments copies the
media reference rather than the bytes, so attachments copied onto posted
documents all reference a single row. Deleting it on behalf of one attachment
destroyed the content of every attachment copied from it, and those
attachments were then skipped silently by UploadToExternalStorage.

The fix only deletes the Tenant Media row when no other Document Attachment
references it, index-backed by the existing key(Key2; "Document Reference ID")
on table 1173.

The build registration of the External Storage - Document Attachments test app
from the original PR (build/groups.json and build/projects/Apps */.AL-Go/
settings.json) is intentionally omitted. Those files do not exist on
releases/28.x, which instead uses wildcard testFolders ("src/Apps/W1/*/Test")
in "build/projects/Apps (W1)/.AL-Go/settings.json" and therefore already picks
the test app up, and has no build/groups.json.

(cherry picked from commit 473bb07)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@JesperSchulz

Copy link
Copy Markdown
Contributor Author

Closing and reopening due to GitHub outage.

@JesperSchulz
Jesper Schulz-Wedde (JesperSchulz) merged commit be24a6b into releases/28.x Aug 20, 2026
96 of 104 checks passed
@JesperSchulz
Jesper Schulz-Wedde (JesperSchulz) deleted the bugs/647080-28xBackportOf646505 branch August 20, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: Apps (W1) Add-on apps for W1 Integration GitHub request for Integration area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants