Skip to content

Keep a secondary's setup copy going when both computers made a row with the same name - #241

Merged
danielehrhardt merged 1 commit into
mainfrom
fix/snapshot-unique-name
Oct 25, 2026
Merged

danielehrhardt merged 1 commit into
mainfrom
fix/snapshot-unique-name

Conversation

@danielehrhardt

Copy link
Copy Markdown
Contributor

Problem

On a device-group secondary, every setup copy from the primary failed with
UNIQUE constraint failed: projects.workspace_id, projects.slug and rolled back as a whole.
The secondary had created a project while standing in, and the primary has its own project
with the same slug in the same workspace (different id). The secondary keeps rows it made
itself, so the primary's row could never be inserted, and nothing else from the copy landed either.

Fix

applySnapshot (packages/core/src/remote/snapshot.ts), on a secondary only:

  • Before writing a row of a table with a UNIQUE index besides the primary key (workspaces, projects, mods; agents keep their own handling), look for a local row with the same key. If it is one this computer made or changed itself, the incoming row is skipped with a warning.
  • Rows the copy wrote that point at the skipped row move to the local one. Rows this computer made itself are never touched. A row that can't move (its own name collides there too) is left to the existing orphan pass.
  • The copy is recorded as applied: the conflict lasts until someone renames one side, so retrying forever would not help.

Plain runners are unaffected (they own no rows, so no lookups run).

Tests

  • remote-snapshot.test.ts: a secondary with its own "earshot" project gets the primary's copy; the agent that pointed at the primary's project now points at the local one; the digest is recorded. Same for a workspace and project pair made on both sides.
  • The first test fails on main with the production error.
  • bun test test/remote-snapshot.test.ts test/replica.test.ts test/stand-in-waiting.test.ts test/remote-link.test.ts: 71 pass. pnpm -r typecheck clean.

…s the primary's

A project (or workspace, mod) a secondary created while standing in, with the
same name as one the primary has, made every snapshot apply fail on the UNIQUE
index and roll back as a whole. The secondary keeps its own row, skips the
primary's with a warning and moves what the copy hangs on it to the local one.
@danielehrhardt
danielehrhardt merged commit 5831326 into main Oct 25, 2026
8 checks passed
danielehrhardt added a commit that referenced this pull request Oct 25, 2026
The merge left duplicate group/replica imports in remote-snapshot.test.ts, and
#241's two same-name tests expected the secondary's project to be skipped. With
#243 the local project steps aside to a free slug instead and both are kept, so
the tests now expect that.
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.

1 participant