Skip to content

fix(data): observeSelectDeep dropped entity id when include carried the id column - #174

Merged
krisnye merged 2 commits into
mainfrom
krisnye/fix-observe-select-deep-id
Aug 16, 2026
Merged

fix(data): observeSelectDeep dropped entity id when include carried the id column#174
krisnye merged 2 commits into
mainfrom
krisnye/fix-observe-select-deep-id

Conversation

@krisnye

@krisnye krisnye commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Problem

observeSelectDeep returns rows with id: undefined whenever the include set carries the id column — which an archetype's runtime components set does, and which real consumers pass directly (e.g. observeSelectDeep(db, db.archetypes.Foo.components)).

pickComponents seeded data.id = entity, then copied every include key from the read values:

const data = { id: entity };
for (const key of includeKeys) data[key] = values[key]; // data["id"] = values["id"]

Since the id-removal change made reads omit id, values["id"] is undefined, and the loop overwrites the correct id. Before id-removal this was masked (the read still carried the right id, so the overwrite was a no-op).

Impact

Any consumer that keys off row.id from a deep select silently gets undefined. This surfaced as a studio layout regression in firefly-platform: the layout system feeds row.id into a per-entity setLayoutIntrinsic transaction; with id undefined the transaction no-ops, so measured element sizes are never recorded, the layout never converges, and top-bar/sidenav controls never settle — breaking three P0 studio E2E tests. Verified end-to-end that this fix resolves them.

Fix

Skip "id" in the copy loop and assign data.id = entity last, so the id column present in the include set can't clobber it. Regression test drives include straight off archetype.components (which carries the id column) — the old tests passed an explicit array without id, so they missed it.

Full data suite green (3023); typecheck clean.

🤖 Generated with Claude Code

krisnye and others added 2 commits August 15, 2026 23:16
…he id column

pickComponents seeded `data.id = entity`, then copied every include key from the
read values. An archetype's runtime `components` set still contains the "id"
column (id is a live column, only typed-out), so passing it as `include` — as
real consumers do — put "id" in the copy loop. Since reads now omit id, the loop
overwrote `data.id` with `values["id"]` (undefined), handing back id-less rows.

Before id-removal this was masked (reads still carried the correct id, so the
overwrite was a no-op). After, every deep-select row got `id: undefined`,
silently breaking consumers that key off `row.id` (e.g. a layout system that feeds
`row.id` back into a per-entity transaction — the transaction no-ops on the
undefined entity and the layout never converges).

Skip "id" in the copy loop and assign `data.id = entity` last. Regression test
drives the include set straight off `archetype.components`, which reproduces the
clobber.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Version bump for the observeSelectDeep id-clobber fix so it can publish.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@krisnye
krisnye merged commit ca8048f into main Aug 16, 2026
3 checks passed
@krisnye
krisnye deleted the krisnye/fix-observe-select-deep-id branch August 16, 2026 06:31
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