DB sync: one asset download returning 404 can block subsequent asset downloads
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 28
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
### Search first
- [x] I searched and no similar issues were found
### What Happened?
In a synced DB graph imported from a Markdown graph, note/asset metadata synced successfully, but most images remained blank on another desktop. Ubuntu had only 11 local asset files despite 55 valid remote assets being available. There was no loading indicator or visible “can’t find file” error for the remaining images. Quitting and reopening the app did not resolve the symptom.
The worker log recorded an asset download failure with HTTP 404 for one genuinely missing image. Inspection of the source maps shipped with both installed desktop builds found a shared asset queue that chains tasks with success-only `p/then`, while the download error handler logs and returns `p/rejected`. This appears to leave the queue rejected, preventing later queued task callbacks from executing.
This report concerns failure isolation in the client download queue, not recovery of the missing image or the original import problem. A controlled reproduction on the latest build has not yet been run.
### Reproduce the Bug
Suggested minimal reproduction based on the observed failure and installed code:
1. In a disposable synced DB graph, have two asset records with remote metadata and no corresponding local files on a second client.
2. Make asset A’s download return HTTP 404 while asset B remains available and valid remotely. A mocked transport is sufficient; do not delete production assets.
3. In the same sync-client session, request A and then B through `thread-api/db-sync-request-asset-download` or the equivalent UI path.
4. Check whether B’s download task executes after A rejects, and whether the UI reports the outstanding failure.
The observed production case had 56 asset records: 55 available remote objects and one missing object. No destructive reproduction was performed on that graph.
### Expected Behavior
A failed asset should remain identifiable/retryable, but unrelated downloads should continue. The UI should surface the individual failure instead of leaving other images blank while sync status appears healthy.
### Screenshots
_No response_
### Files
Sanitized excerpt from the Ubuntu worker log:
```clojure
[frontend.worker.sync.assets]
{:db-sync/request-asset-download-failed
{:repo "logseq_db_"
:asset-uuid #uuid "00000000-0000-0000-0000-000000000001"
:error #error
{:message "download asset failed"
:data {:type :rtc.exception/download-asset-failed
:data {:status 404}}}}}
```
The UUID above is a placeholder. No private graph, credentials, account identifiers, or server address are included.
Installed source-map evidence, `frontend/worker/sync.cljs`, `enqueue-asset-task!`:
```clojure
(defn- enqueue-asset-task!
[client task]
(when-let [queue (:asset-queue client)]
(swap! queue
(fn [prev]
(p/then prev (fn [_] (task)))))))
```
`frontend/worker/sync/assets.cljs`, `request-asset-download!`, ends its queued task with:
```clojure
(p/catch (fn [e]
(log-request-asset-download-failed! repo asset-uuid e)
(p/rejected e)))
```
Suggested investigation: keep per-task rejection visible to its caller while making the shared queue tail recover before scheduling subsequent tasks. Add a regression test for a rejected download followed by a successful download in the same client session.
### Browser, Desktop or Mobile Platform Information
- Ubuntu desktop: CLI revision `d921807-dirty`, build time `2026-05-27T13:27:05.928372453Z`; worker revision `d921807-dirty`, build time `2026-05-27T13:26:20.402160073Z`. The dirty revision means local build differences cannot be ruled out.
- macOS desktop: Logseq 2.0.1, revision `b09316a`, July 13, 2026 build.
- Both installed source maps contain the queue/error-handler pattern above.
- Self-hosted DB sync with encrypted assets. The official hosted service was not tested.
- Latest upstream build has not been tested.
### Additional Context
The self-hosted server returned 200 for all 55 available assets and 404 for the one missing asset. On Ubuntu, requesting the remaining 44 valid assets explicitly through the existing Logseq worker connection, while skipping the missing one, downloaded them successfully. All 55 local files then matched the SHA-256 checksums stored in their asset records. Asset records were unchanged by this recovery.
After recovery, the WebSocket was open, local and remote transaction counters matched, pending local/server/asset counts were zero, and `last-error` was null. This verifies the available objects can be served and decrypted; it does not patch the queue or prove UI rendering on every device.
I searched existing issues and the forum and did not find an exact match for this queue-blocking failure. Potentially related: https://github.com/logseq/db-test/issues/628 (“404 Asset Error on Start”), which described repeated 404s without loss of functionality in an older RTC implementation. This report concerns unrelated downloads being blocked after a failure.
### Are you willing to submit a PR? If you know how to fix the bug.
- [ ] I'm willing to submit a PR (Thank you!)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with enqueue-asset-task! in frontend/worker/sync.cljs and request-asset-download! in frontend/worker/sync/assets.cljs, then trace the asset queue entry point thread-api/db-sync-request-asset-download. Add a regression test for a 404 followed by a successful download in one client session. Done means the failed asset remains visible or retryable, while the later download still executes and its result is reported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure
- Domain
- database, desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100