You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found while implementing #15742 (the objects[].fields half of the same defect class); filed as a finding only, not claimed.
validateStackExpressions throws on a non-record entry of a flow's nodes list. It is the same class #15552 / #15636 / #15742 closed for stack COLLECTIONS, but no sweep sees it: non-record-object-entry.test.ts drives collections (stack.flows, objects[].fields, …), never a flow's inner graph, and this reader declares no asArray helper for the coercion greps to find — it casts inline.
Measured
On fd82de279 (the #15742 branch, i.e. WITH that card's fix), calling the rule directly, one line per shape:
An empty item in a YAML nodes: list deserialises to null, so this is an authorable shape, exactly as it was for fields:.
The lines
packages/lint/src/validate-expressions.ts, both inside validateStackExpressions:
the top-level flow walk — const nodes = Array.isArray(flow.nodes) ? (flow.nodes as AnyRec[]) : [];, whose very next statement is nodes.find(n => n.type === 'start'), the throw above;
the per-graph walk — for (const node of graph.nodes as unknown as AnyRec[]), then node.config. graph.nodes comes from collectFlowGraphs (@objectstack/spec/automation), so whether a non-record member can reach it depends on that producer; it was NOT measured here and is the contract-first question below.
Array.isArray proves the LIST, never its MEMBERS — the same sentence #15742's fix removed one file-level reader below.
Notes for whoever takes it
recordsOf (object-graph.ts) is the one home of this coercion, and re-pointing here adds no copy for collection-coercion-single-copy.test.ts to count.
Where the repair belongs is a real question, not a formality: for graph.nodes the producer is collectFlowGraphs, and if IT is what admits a non-record node, the fix is upstream (contract-first) rather than a second guard at the consumer.
The pin is the open part: today's sweep cannot express "a flow's inner node list", so a fix needs either a new arm in non-record-object-entry.test.ts for graph-shaped members, or a local test — that choice is worth stating in the ruling rather than left to the dev.
Filed by the domain:devx execution seat (session 012zGPuVVX3deAx9LdjK8jCk) on behalf of the os-dev on #15742 (PR #15791), whose issue creation was classifier-blocked. Bare for triage — the repair may belong upstream in @objectstack/spec/automation (collectFlowGraphs), which is a ruling, not a dev's call.
Found while implementing #15742 (the
objects[].fieldshalf of the same defect class); filed as a finding only, not claimed.validateStackExpressionsthrows on a non-record entry of a flow'snodeslist. It is the same class #15552 / #15636 / #15742 closed for stack COLLECTIONS, but no sweep sees it:non-record-object-entry.test.tsdrives collections (stack.flows,objects[].fields, …), never a flow's inner graph, and this reader declares noasArrayhelper for the coercion greps to find — it casts inline.Measured
On
fd82de279(the #15742 branch, i.e. WITH that card's fix), calling the rule directly, one line per shape:Reproduce:
An empty item in a YAML
nodes:list deserialises tonull, so this is an authorable shape, exactly as it was forfields:.The lines
packages/lint/src/validate-expressions.ts, both insidevalidateStackExpressions:const nodes = Array.isArray(flow.nodes) ? (flow.nodes as AnyRec[]) : [];, whose very next statement isnodes.find(n => n.type === 'start'), the throw above;for (const node of graph.nodes as unknown as AnyRec[]), thennode.config.graph.nodescomes fromcollectFlowGraphs(@objectstack/spec/automation), so whether a non-record member can reach it depends on that producer; it was NOT measured here and is the contract-first question below.Array.isArrayproves the LIST, never its MEMBERS — the same sentence #15742's fix removed one file-level reader below.Notes for whoever takes it
recordsOf(object-graph.ts) is the one home of this coercion, and re-pointing here adds no copy forcollection-coercion-single-copy.test.tsto count.graph.nodesthe producer iscollectFlowGraphs, and if IT is what admits a non-record node, the fix is upstream (contract-first) rather than a second guard at the consumer.non-record-object-entry.test.tsfor graph-shaped members, or a local test — that choice is worth stating in the ruling rather than left to the dev.fields:list — an inline cast the asArray sweeps could not see #15742 is not addressed here; it landed theobjects[].fieldsreader only, and its card body already flagged these two lines as unmeasured at filing time. This card carries the measurement.Filed by the
domain:devxexecution seat (session012zGPuVVX3deAx9LdjK8jCk) on behalf of theos-devon #15742 (PR #15791), whose issue creation was classifier-blocked. Bare for triage — the repair may belong upstream in@objectstack/spec/automation(collectFlowGraphs), which is a ruling, not a dev's call.Generated by Claude Code