Fix external integration URL updates not reflecting without app restart - #13059
Conversation
There was a problem hiding this comment.
1 issue found across 3 files
Confidence score: 3/5
- In
app_detail.dart, a late setup-check response can update the UI with completion status for a previous URL after a reload, showing stale configuration state to users; guard responses by the requested URL or configuration generation before updating state.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="app/lib/pages/apps/app_detail/app_detail.dart">
<violation number="1" location="app/lib/pages/apps/app_detail/app_detail.dart:269">
P2: When an earlier setup check completes after this reload check, it can display the completion status for the old URL. Guard setup-check responses with the requested URL or a configuration generation before updating `setupCompleted` and triggering auto-install.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Git-on-my-level
left a comment
There was a problem hiding this comment.
Thanks for the clean, well-scoped fix and the honest verification notes — the regression tests are exactly the right shape for #3309.
What I verified:
- All 9 tests in
app/test/unit/app_detail_config_changed_test.dartran and passed in CI (confirmed from the test-run diagnostics), including the auth-step-only and setup-completed-only change cases that reproduce the bug. - The
Dart Analyze & Testsfailure is not from this PR: the single failing test islocal_segment_store_test.dart→ "CaptureProvider listener persists when a live session is active" (expects a persisted-segment content hash, gets the empty-input hash). That is the capture/WAL subsystem, untouched by this diff, and main-branch runs of the same suite were green today — no action needed from you on that one.
Blocking (small):
- The
Formattingcheck fails onapp/test/unit/app_detail_config_changed_test.dart: lines 69–70 are 121 characters, just over the 120-column limit, sodart format --line-length 120 --set-exit-if-changedrejects the file. Runningdart format --line-length 120 app/test/unit/app_detail_config_changed_test.dartand pushing should turn it green.
Non-blocking, worth considering:
_onExternalIntegrationUpdated()inapp/lib/pages/apps/app_detail/app_detail.dartduplicates the instructions-fetch block frominitState(thegetAppMarkdown→](assets/rewrite →setState(instructionsMarkdown = ...)sequence). Extracting one helper called from both places would remove the copy and make it natural to guard the async callbacks with the path/config they were issued for, so a late-arriving older fetch cannot overwrite newer instructions orsetupCompletedstate.- The doc comment on
hasAppDetailConfigChangedinapp/lib/pages/apps/app_detail/app_detail_config.dartsays it compares "fields shown on the app detail page", butExternalIntegration.toJson()also includes fields the page does not render (actions,triggers_on,chat_tools_manifest_url,mcp_server_url). The wider comparison is harmless today (worst case an extra refresh); trimming the comment or the compared field set would make the contract read true.
Once formatting is green, this still needs a maintainer to manually walk the #3309 repro (edit only an auth-step or setup-completed URL, save, return to the detail page) before merge — the save/return flow has no automated coverage and the unit tests stop at the comparison helpers.
This review was produced by automated tooling on behalf of the Omi maintainers.
by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with need human response.
…l page Co-authored-by: Apoorv Darshan <apoorvdarshan@gmail.com>
Co-authored-by: Apoorv Darshan <apoorvdarshan@gmail.com>
Co-authored-by: Apoorv Darshan <apoorvdarshan@gmail.com>
Extract a single setup-instructions markdown loader used by initState and _onExternalIntegrationUpdated. Ignore stale in-flight setup-check and markdown responses with generation counters plus requested URL/path checks so an older URL cannot overwrite newer detail-page state. Failure-Class: none Co-authored-by: Apoorv Darshan <apoorvdarshan@gmail.com>
317f901 to
d7e4ef9
Compare
|
Addressed the requested changes on
Please re-review. Dart Analyze still cannot be run in this VM (no Flutter SDK); CI is the authority. The |
|
Thanks @apoorvdarshan — all three items from the earlier review are addressed on d7e4ef9, verified against the diff and CI:
Also confirmed: Remaining before merge: the unit tests stop at the comparison helpers, so the #3309 repro itself (edit only an auth-step or setup-completed URL → save → return to the detail page) still needs one manual walkthrough on a device/emulator. That's the only open item I'm aware of. This review was produced by automated tooling on behalf of the Omi maintainers. by AI on behalf of David — the manual #3309 walkthrough above is the one item needing a maintainer's hands before merge; no other follow-up is pending. |
Dismissed: all items from this review are resolved at d7e4ef9 — formatting is green (no lines over 120 columns in app_detail_config_changed_test.dart), the instructions-fetch block is deduplicated into _loadSetupInstructionsMarkdown with stale-response guards, and hasExternalIntegrationChanged now matches its documented user-visible URL-field contract with a covering test.
What changed and why
Fixes #3309. After saving integration URL changes on the update-app screen, the app detail page kept using a stale local
Appobject because both refresh paths only comparedappHomeUrl,name, anddescription. Edits limited to auth-step URLs, setup-completed URLs, webhook URLs, or setup-instructions paths therefore did not trigger a refresh until a full app restart.This PR:
_loadSetupInstructionsMarkdownhelper used byinitStateand_onExternalIntegrationUpdated.checkSetupCompleted/getAppMarkdowncallbacks with generation counters plus requested URL/path checks so a stale response cannot overwrite newer config.An accidental later push had truncated
app_detail.dart; that file is restored. Diff is the intended 3-file set only.Product invariants affected
none
How it was verified
app/test/unit/app_detail_config_changed_test.dartlines 69–70 are now well under 120 columns (the Formatting failure).git diff --statvs BasedHardware/omimainis 3 files, +259 / −44 (app_detail.dart,app_detail_config.dart, the unit test).mainpassed. Flutter SDK is not in this VM, so Dart Analyze anddart formatwere not executed here; CI is the authority.local_segment_store_test.dartis out of scope; if Dart Analyze & Tests still fails on that capture/WAL flake, it is unrelated.Manual verify path:
Tests
app/test/unit/app_detail_config_changed_test.dartcovers auth-step URL-only changes, setup-completed URL-only changes, webhook URL changes, hidden-field no-ops, and name changes.Failure class (fixes)
Failure-Class: none