Skip to content

Report a non-committed shared-structure save as not-saved (v5.0) - #1157

Merged
kriszyp merged 3 commits into
v5.0from
kris/savestructures-commit-signal-v50
Jun 8, 2026
Merged

kriszyp merged 3 commits into
v5.0from
kris/savestructures-commit-signal-v50

Conversation

@kriszyp

@kriszyp kriszyp commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

v5.0 backport of the Record id is not defined for N desync fix (main: #1154). This is the deployed line where the error fires on CDI rt-dev.

RecordEncoder.saveStructures returned undefined when the structure-save txn aborted (ERR_ALREADY_ABORTED swallowed by transactionSync) — and the success path also fell through to undefined. msgpackr only re-packs on === false, so a swallowed abort looked like success and the already-encoded record (referencing the new structure id) was persisted even though the structure was never saved → Record id is not defined for N on a fresh reader.

  • Returns true only on a committed save, false otherwise (CAS conflict or aborted txn).
  • Bumps msgpackr 1.11.13 → 1.11.14 (kriszyp/msgpackr#186), which marks structures uninitialized on save-failure so the re-pack reloads durable structures, rebuilds the transition trie, and re-mints + re-saves. Both halves are required — return false alone doesn't recover (the re-pack reused the cached transition).

Validated end-to-end (~/dev/scripts/savestructures-abort-repro.cjs). Independent of the typed-structs work — this is the classic shared-structure path. The auto-cherry-pick can't carry this cleanly (main bumps msgpackr to 2.0.3; v5.0 needs 1.11.14), hence a dedicated PR.

🤖 Generated by Claude (Opus 4.7).

Backport to v5.0 (deployed line). RecordEncoder.saveStructures wrapped
rootStore.transactionSync, which returns `undefined` when the structure-save txn
was aborted (ERR_ALREADY_ABORTED swallowed); the success path also fell through
to `undefined`. msgpackr only re-packs on `=== false`, so a swallowed abort
looked like success and the already-encoded record (referencing the new structure
id) was written even though the structure was never persisted → "Record id is not
defined for N" on a fresh reader (the dominant CDI rt-dev error).

Return `true` only on a committed save, `false` otherwise. Bumps msgpackr to
1.11.14, which marks structures uninitialized on save-failure so the re-pack
reloads durable structures, rebuilds the trie, and re-mints + re-saves.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@socket-security

socket-security Bot commented Jun 8, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedmsgpackr@​1.11.13 ⏵ 1.11.1499100100 +194100

View full report

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request upgrades msgpackr to version 1.11.14 and fixes an issue in RecordEncoder.ts where aborted transactions in saveStructures returned undefined instead of false, causing msgpackr to write records referencing unsaved structures. The reviewer identified an issue where this.structureUpdate is updated inside the transaction callback before the commit is confirmed. If the transaction aborts, this side-effect remains, which could lead to incorrect metadata flags. The reviewer suggested assigning this.structureUpdate only after a successful commit.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread resources/RecordEncoder.ts Outdated
Comment on lines +233 to +238
this.structureUpdate = structures;
return true;
},
{ retryOnBusy: true }
);
return committed === true ? true : false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If the transaction aborts or fails to commit (e.g., due to a conflict), this.structureUpdate is still set to structures because the assignment happens inside the transaction callback before the commit is confirmed. This can lead to incorrect metadata flags (like HAS_STRUCTURE_UPDATE) being written to the audit log for failed/aborted transactions.

To prevent this side-effect, this.structureUpdate should only be assigned if the transaction successfully commits.

\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\t{ retryOnBusy: true }\n\t\t\t\t);\n\t\t\t\tif (committed === true) {\n\t\t\t\t\tthis.structureUpdate = structures;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch — fixed in bc61512. Moved this.structureUpdate = structures out of the transactionSync callback so it's only assigned when committed === true. On an aborted/declined txn it now stays unset, so no spurious HAS_STRUCTURE_UPDATE can be flagged for an unpersisted structure. Also dropped the redundant ternary. — Claude

@kriszyp
kriszyp marked this pull request as ready for review June 8, 2026 14:17
@kriszyp
kriszyp requested a review from a team as a code owner June 8, 2026 14:17
kriszyp and others added 2 commits June 8, 2026 14:28
Move `this.structureUpdate = structures` out of the transactionSync
callback so it is only set on a confirmed commit. Setting it inside the
callback left it dangling on an aborted txn, which could flag a spurious
HAS_STRUCTURE_UPDATE in the audit log for a structure that was never
persisted. Addresses review feedback.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pre-existing format-check failure on the v5.0 line (unformatted code
from the RocksDB-config change); not related to the structure-save fix,
folded in here to get the Format Check green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@kriszyp
kriszyp merged commit 0f38c49 into v5.0 Jun 8, 2026
18 of 22 checks passed
@kriszyp
kriszyp deleted the kris/savestructures-commit-signal-v50 branch June 8, 2026 20:43
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