Skip to content

fix(web/ctx): Sync All toasts sync_success for non-ok Settings statuses (error, aborted) #799

@memtomem

Description

@memtomem

Problem

mm web Context Gateway "Sync All" inspects the Settings sync response body
for status === 'needs_confirmation' (#774, PR #798) but treats every other
non-ok per-result status as full success. The route at
/api/context/settings/sync (generate_all_settings,
packages/memtomem/src/memtomem/context/settings.py:261) can return five
status values per generator:

status meaning
ok merged + written
skipped runtime not installed / no canonical source (benign)
error canonical or target file is malformed JSON
needs_confirmation host-write target without allow_host_writes=true
aborted mtime conflict during merge (concurrent write race)

After PR #798 the JS at web/static/context-gateway.js:248-265 only
branches on needs_confirmation. So:

  • error → still toasts settings.ctx.sync_success even though the merge
    failed because of malformed JSON.
  • aborted → still toasts sync_success even though the merge was
    rolled back due to a concurrent writer.
  • skipped → benign; success toast is fine.

This is the same class of bug as #774 (resp.ok hides per-result failure)
just with different status values.

Repro

  1. Make ~/.claude/settings.json malformed (e.g. trailing comma).
  2. mm web → Sync All.
  3. /api/context/settings/sync returns 200 with
    {"results": [{"name": "claude_settings", "status": "error", ...}]}.
  4. UI toasts "Sync complete" — lie.

Proposed shape

Widen the predicate in the Sync All handler to surface a structured
toast for any result.status not in {"ok", "skipped"}:

i18n keys can mirror the existing per-status messages used elsewhere
(settings.ctx.mtime_conflict, generic toast.sync_failed). The
dedicated Settings panel's Sync Now button (settings-hooks-watchdog.js:150)
has the same gap and may be in scope or a separate cut.

Test shape

Extend tests/test_i18n.py::test_issue_774_sync_all_inspects_settings_body
(or add a sibling test) to symmetric-pin all four non-ok branches:
positive marker for each handled status + inverted assertion that the
unconditional sync_success path is gone for those statuses.

Refs

Out of scope

The Settings panel's Sync Now (settings-hooks-watchdog.js:150)
host-write confirmation flow itself (Option 2 from #774). That's a
larger UX change tracked separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions