Measured while implementing objectui#6708's diagnostic, outside its fence, so filed separately. Observation-class: nothing is known to depend on it today.
The fact, measured on faac0d935
SchemaRenderer's evaluation memo rebuilds the props bag under a BARE truthiness guard:
if (newSchema.props) {
const newProps = { ...newSchema.props };
for (const [key, val] of Object.entries(newProps)) {
newProps[key] = evaluator.evaluate(val);
}
newSchema.props = newProps;
}
Spreading a string produces its character indices. So a node written { type: 'card', props: 'not-a-bag' } arrives at the createElement spread carrying nine React props named 0 through 8, one per character, and they are spread onto the component.
This was not deduced — it is what turned an objectui#6708 pin red. That test expected silence for a degenerate bag; the diagnostic instead reported nine dropped keys and told the author that the member 0 of schema was undefined. The published fix reads the AUTHORED bag off the original schema so it stays silent there, which means the underlying spread is still exactly as described.
Why it looks like an oversight rather than a decision
The sibling properties branch a few lines above carries a deliberately WIDER guard and says why in its comment: a degenerate properties must not have its shape reinterpreted by an object spread, because that value feeds the hoist. The props branch has no equivalent guard, and its value feeds the React-prop spread instead. Same hazard, one of the two channels guarded.
Blast radius, honestly bounded
Zero in-repo authored nodes carry a non-object props — the objectui#6708 census walked every JSON document, every json doc fence and every TypeScript object literal for nodes with both type and props and found no such node. So this is a latent shape, not a live failure, and the arm that follows from that may well be "leave it". What makes it worth recording is that the two bags disagree about a hazard the code itself documents on one side.
Arms, if anyone takes it
- widen the
props guard to match properties' — smallest, and makes the documented reasoning apply to both channels;
- leave it and record the asymmetry as intended, in which case the
properties comment should say why only one side needs it.
Either way it needs someone to decide, not to guess.
Related: objectui#6708 (where it was measured), objectui#5123 (the two-bag precedence ruling).
Generated by Claude Code
Measured while implementing objectui#6708's diagnostic, outside its fence, so filed separately. Observation-class: nothing is known to depend on it today.
The fact, measured on
faac0d935SchemaRenderer's evaluation memo rebuilds thepropsbag under a BARE truthiness guard:Spreading a string produces its character indices. So a node written
{ type: 'card', props: 'not-a-bag' }arrives at thecreateElementspread carrying nine React props named0through8, one per character, and they are spread onto the component.This was not deduced — it is what turned an objectui#6708 pin red. That test expected silence for a degenerate bag; the diagnostic instead reported nine dropped keys and told the author that the member
0of schema was undefined. The published fix reads the AUTHORED bag off the original schema so it stays silent there, which means the underlying spread is still exactly as described.Why it looks like an oversight rather than a decision
The sibling
propertiesbranch a few lines above carries a deliberately WIDER guard and says why in its comment: a degeneratepropertiesmust not have its shape reinterpreted by an object spread, because that value feeds the hoist. Thepropsbranch has no equivalent guard, and its value feeds the React-prop spread instead. Same hazard, one of the two channels guarded.Blast radius, honestly bounded
Zero in-repo authored nodes carry a non-object
props— the objectui#6708 census walked every JSON document, everyjsondoc fence and every TypeScript object literal for nodes with bothtypeandpropsand found no such node. So this is a latent shape, not a live failure, and the arm that follows from that may well be "leave it". What makes it worth recording is that the two bags disagree about a hazard the code itself documents on one side.Arms, if anyone takes it
propsguard to matchproperties' — smallest, and makes the documented reasoning apply to both channels;propertiescomment should say why only one side needs it.Either way it needs someone to decide, not to guess.
Related: objectui#6708 (where it was measured), objectui#5123 (the two-bag precedence ruling).
Generated by Claude Code