Skip to content

fix(sync): let one bad roster file, object or snapshot stop only itself - #1830

Merged
A-EDev merged 3 commits into
mainfrom
fix/sync2-oversized-item
Nov 7, 2026
Merged

A-EDev merged 3 commits into
mainfrom
fix/sync2-oversized-item

Conversation

@A-EDev

@A-EDev A-EDev commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A roster file, log object, key or blob over its size limit, or refused for itself, ended the whole sync. It now stops only that item, and it is read again on a later sync. That means an oversized item and a 4xx answer other than 401, 407, 408 and 429, including 403. A linked profile whose snapshot can't be read yet waits for a later sync while the others go on.

Everything else still fails the sync: the network, 5xx, 3xx, 401, 407, 408, 429 and a refused login. The saved cursor and tag don't move, so the next sync reads the item. This is the same list as Flow Desktop's #459. To tell an oversized answer from other bad answers, as Desktop does, StoreException.TooLarge is new, and Malformed no longer stops only one item.

Roster files on a file store are now read one at a time, lowest seq first. Only entries valid against their chain are held, using the check the fork rule already applies (ValidEntries, moved out of validTree). One pull reads at most 16,384 files and 64 MiB, the limits Flow Desktop uses.

Related issue

None.

Change type

  • Bug fix
  • Feature
  • Refactor or maintenance
  • Build, packaging, or CI
  • Documentation

Validation

  • ./gradlew --offline ... :app:testGithubDebugUnitTest --tests 'io.github.aedev.flow.sync2.*': 313 tests, 0 failed.

  • ./gradlew --offline ... ktlintCheck: passed.

  • python3 .github/scripts/nightly_notes.py --check: passed.

  • OneBadItemTest: 12 passed. An earlier commit's mutation run covered the chain check, read limit, retry, snapshot wait, rate-limit rule and item rule. It wasn't repeated for those.

  • New in the last commit, and failing before it: 302, 401, 407, 408, 429, 500 and 503 on an object, a chain box, a roster file and a log file fail the sync, and the next read gets the item; 400, 403, 410, 451 and an oversized answer stop only the item.

  • Each of these made tests fail when tried: 401, 407, 408 or 429 left out of the list, 403 added, 5xx or 3xx counted as about the item, every status or no status counted as about the item, and an oversized answer failing the sync.

  • ./gradlew :app:assembleGithubDebug: not run locally, CI builds it.

  • ./gradlew :app:testGithubDebugUnitTest: full suite not run locally, CI runs it.

  • I manually tested the affected behavior on an Android device or emulator: not done.

Test device and Android version: none.

Risk and compatibility

Background sync only. A server error shows as a refused request, which WorkManager doesn't retry early, so the next sync is the next scheduled one or Sync now. A chain box that's oversized or refused for itself leaves objects under that older epoch unreadable, so those logs stop at the first such object. The 64 MiB and 16,384 file limits are chosen far above a real roster, not measured. A folder that fills that read limit with junk ahead of real entries leaves this device on an older roster until the junk goes. A store could already hide entries.

  • The change does not introduce secrets, private data, or unexpected telemetry.
  • New user-facing text uses Android string resources, or this PR adds none.
  • Dependency and lockfile changes are intentional and limited to this PR. There are none.
  • Room schema changes include the required version bump and migration, or this PR does not change the Room schema.
  • Breaking changes and upgrade steps are clearly documented. There are none.

Copilot AI balanced review requested due to automatic review settings November 7, 2026 13:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Nov 7, 2026
@A-EDev
A-EDev merged commit 45bcedd into main Nov 7, 2026
9 checks passed
@A-EDev
A-EDev deleted the fix/sync2-oversized-item branch November 7, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants