microsoft / microsoft/BCApps

[Bug]: External Storage - Document Attachments deletes the attached file on posting (regression between v28.3 and v28.4) Summary

Open
#11,169 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Team: Integrations
Dominant language
AL
Stars
683
Forks
459
Avg merge
3d 26m
Merged PRs (30d)
633

Description

Describe the issue

When a document with an attachment stored via "External Storage - Document Attachments" is posted, the underlying file in external storage (Azure Blob Storage) is deleted and never recreated for the posted document. Both the unposted and posted Document Attachment records survive and end up pointing to the exact same External File Path, but the blob itself no longer exists in the storage container. Confirmed NOT related to the "Delete External File on Attachment Delete" setup toggle.
Confirmed working correctly on extension version 28.3.52162.52273 and broken on 28.4.53241.53312 — same tenant setup, same File Account, same flow.
Environment
App: External Storage - Document Attachments (Microsoft)
Working version: 28.3.52162.52273
Broken version: 28.4.53241.53312
Storage provider: Azure Blob Storage
Affected document type(s): Purchase Invoice (Purchase Header -> Purch. Inv. Header); also reproduced on Purchase Quote (custom No. series) -> posted document copy

Expected behavior

Expected behavior
The file should be reachable from the posted document's attachment after posting (either by relocating/duplicating the blob, or simply not deleting it).
Actual behavior
The blob does not exist under .../Purchase_Header/... anymore.
The blob does not exist under .../Purch._Inv._Header/... either (no new copy was created there).
Opening the attachment from the Posted Purchase Invoice in Business Central fails (file not found).
Neither Document Attachment record (#1 or #2) is deleted from the table — both persist with identical External File Path values.
The "Delete External File on Attachment Delete" toggle on the File Account was disabled during testing; the file was still deleted on the broken version. On the working version (28.3), disabling the same toggle in the same scenario prevents the loss (file opens correctly after posting).
The Skip Delete On Copy field on both resulting Document Attachment rows is unchecked/false in both cases; there is no setup-page option to change its default.
Root cause (hypothesis based on available symbols)
Document Attachment Mgmt.CopyAttachmentsForPostedDocs copies the Document Attachment metadata row to the posted document without creating an independent blob for it - both rows end up referencing the same External File Path. The external-storage-specific logic that runs as part of (or immediately after) that copy appears to delete the source file unless Skip Delete On Copy is true on the copied-from record, and this deletion path does not consistently honor the File Account's "Delete External File on Attachment Delete" setting across app versions (works as expected on 28.3, ignored on 28.4).
This may be related to the pattern already reported in microsoft/BCApps#8162 ("External Storage - Document Attachments: Deleting a Document Attachment does not remove the file from external storage"), which points at fragility in DA External Storage Impl.'s delete-related event subscribers (OnAfterDeleteEvent firing after the record is already gone). That issue describes files being orphaned (not deleted); this report describes the opposite and more severe outcome - the file being deleted with no surviving copy at all - but both point at the same area of the code being unreliable across versions.
Impact
Silent, permanent data loss of attached files on posting for any document type that copies attachments to a posted record, once "External Storage - Document Attachments" is enabled. No error is raised to the user; the posting completes successfully and the loss is only discovered when someone tries to open the attachment later.
Suggested fix
Make the copy-to-posted-document flow either (a) duplicate the blob to a path scoped to the posted document before any delete, or (b) never delete the source blob when the destination attachment record still references the identical External File Path (reference-count check), regardless of app version.
Ensure "Delete External File on Attachment Delete" is consistently honored for every delete path that touches an externally-stored attachment, including internal cleanup during posting - not just explicit user-initiated deletes.
Expose Skip Delete On Copy as a configurable default on the File Account / Document Attachment external storage setup page, so customers aren't required to write a custom event subscriber to prevent data loss.
Evidence available on request
Screenshots of Document Attachment records showing both rows with identical External File Path and Skip Delete On Copy = false.
Extension version numbers from both the working (28.3) and broken (28.4) environments.
Confirmation that the "Delete External File on Attachment Delete" toggle state does not change the outcome on 28.4, but does on 28.3.

Steps to reproduce

Steps to reproduce
On a company with "External Storage - Document Attachments" enabled and a File Account configured (Azure Blob Storage), create a new Purchase Invoice.
Attach a file to the Purchase Invoice (Document Attachment record #1 is created; file uploads to <Company>/<EnvironmentHash>/Purchase_Header/<file>-<GUID>.<ext> in the storage container).
Post the Purchase Invoice.
A new Document Attachment record #2 is created for the resulting Posted Purchase Invoice header. It points to the same External File Path as record #1 (folder still says Purchase_Header, not relocated to Purch._Inv._Header).
Try to open the attachment from the Posted Purchase Invoice.

Additional context

No response

I will provide a fix for a bug
  • I will provide a fix for a bug

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing Document Attachment Mgmt.CopyAttachmentsForPostedDocs and the related DA External Storage Impl. delete event subscribers, using the Purchase Invoice posting reproduction described in the issue. Compare the 28.3 and 28.4 behavior around the shared External File Path and Delete External File on Attachment Delete setting. Done means posting preserves a reachable attachment on the posted document and the setting is honored during cleanup.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure
Domain
backend, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.