Skip to content

feat(datastore): Refuse configure from a secondary isolate (#5302) - #7271

Draft
cadivus wants to merge 1 commit into
feat/isolate-category-guardrailsfrom
feat/isolate-guard-datastore
Draft

feat(datastore): Refuse configure from a secondary isolate (#5302)#7271
cadivus wants to merge 1 commit into
feat/isolate-category-guardrailsfrom
feat/isolate-guard-datastore

Conversation

@cadivus

@cadivus cadivus commented Aug 12, 2026

Copy link
Copy Markdown
Member

⚠️ Read the last bullet — the Auth and push guards are BLOCKED, and I stopped rather than ship them unverified. First per-category guardrail for #5302, stacked on #7270.

  • AmplifyDataStore.configure now fails fast with a PluginError in an Isolate.spawned isolate, naming the real cause (native DataStore is a single instance per process) and where to go instead. Checked before the config check, because being on the wrong isolate cannot be fixed by supplying a config.
  • Detection is ServicesBinding.rootIsolateToken != null — true for an app main isolate and a headless FlutterEngine, so it cannot fire in a single-isolate app. Predicate duplicated from the canonical @internal getter in amplify_flutter (each copy comments the other) because amplify_datastore does not depend on amplify_flutter; no common Flutter-capable package exists, and amplify_core is deliberately Flutter-free.
  • 4 new tests, all in CI: guard fires in a secondary isolate with the right message, does not fire on the root isolate (reaches the pre-existing ConfigurationError). Full suite 121/121 green, zero regression.
  • 🛑 Auth + push guards blocked. amplifyBackgroundProcessing runs addPlugins([AmplifyAuthCognito(), AmplifyPushNotificationsPinpoint()]) in a headless engine, so both those guards depend on the load-bearing claim that a headless FlutterEngine reports a non-null root-isolate token — and it cannot be CI-verified: the push example has no e2e_android leg and no push package in the repo has an integration_test/ dir. Details in the task report; DataStore is unaffected because it is not in that path.

@codecov-commenter

codecov-commenter commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (feat/isolate-category-guardrails@16686a0). Learn more about missing BASE report.

Additional details and impacted files
@@                         Coverage Diff                         @@
##             feat/isolate-category-guardrails    #7271   +/-   ##
===================================================================
  Coverage                                    ?   32.68%           
===================================================================
  Files                                       ?       34           
  Lines                                       ?     2374           
  Branches                                    ?      915           
===================================================================
  Hits                                        ?      776           
  Misses                                      ?     1598           
  Partials                                    ?        0           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cadivus
cadivus force-pushed the feat/isolate-category-guardrails branch from 8636810 to 16686a0 Compare August 12, 2026 16:46
First of the per-category #5302 guardrails. DataStore is backed by a
process-wide native SDK, so `AmplifyDataStore.configure` now fails fast in an
isolate started with `Isolate.spawn` instead of either dying on the platform
channel or quietly attaching to the root isolate's already-configured native
SDK.

The guard is checked before the config check: being on the wrong isolate cannot
be fixed by supplying a config.

Detection is `ServicesBinding.rootIsolateToken != null`, which is true for an
app's main isolate and for a headless `FlutterEngine`, so it cannot fire in a
single-isolate app. The predicate is duplicated from the canonical
`@internal` getter in amplify_flutter because amplify_datastore does not depend
on amplify_flutter, and adding that dependency to share four lines would invert
the plugin dependency graph. The comment on each copy points at the other.

121 tests pass in amplify_datastore (117 pre-existing, 4 new).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants