{"record":{"id":"79cd88ff98f5f083","repo":"different-ai/openwork","slug":"expected-key-to-be-an-array","errorCode":null,"errorMessage":"Expected '${key}' to be an array.","messagePattern":"Expected '(.+?)' to be an array\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/interpreter/model.ts","lineNumber":168,"sourceCode":"    `Syntax '${kind}' is not supported in CodeMode. ${supportedSyntaxMessage}`,\n    node,\n    \"UnsupportedSyntax\",\n    [supportedSyntaxMessage],\n  )\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === \"object\" && value !== null\n\nexport const asNode = (value: unknown, context: string): AstNode => {\n  if (!isRecord(value) || typeof value.type !== \"string\") {\n    throw new InterpreterRuntimeError(`Invalid AST node while reading ${context}.`)\n  }\n  return value as AstNode\n}\n\nexport const getArray = (node: AstNode, key: string): Array<unknown> => {\n  const value = node[key]\n  if (!Array.isArray(value)) throw new InterpreterRuntimeError(`Expected '${key}' to be an array.`, node)\n  return value\n}\n\nexport const getString = (node: AstNode, key: string): string => {\n  const value = node[key]\n  if (typeof value !== \"string\") throw new InterpreterRuntimeError(`Expected '${key}' to be a string.`, node)\n  return value\n}\n\nexport const getBoolean = (node: AstNode, key: string): boolean => {\n  const value = node[key]\n  if (typeof value !== \"boolean\") throw new InterpreterRuntimeError(`Expected '${key}' to be a boolean.`, node)\n  return value\n}\n\nexport const getOptionalNode = (node: AstNode, key: string): AstNode | undefined => {\n  const value = node[key]\n  if (value === undefined || value === null) return undefined","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/interpreter/model.ts#L150-L186","documentation":"getArray reads a property off an AstNode and asserts it is an Array, throwing InterpreterRuntimeError (with the offending node attached) otherwise. The interpreter uses it for node fields that hold child lists (e.g. params, body items), so a non-array value means the AST shape diverges from what the visitor expects.","triggerScenarios":"Calling getArray(node, key) where node[key] is undefined, null, an object, or a single node instead of an array — e.g. a variant of the grammar where a block's body is a single statement rather than a list.","commonSituations":"Parser/interpreter version mismatch on grammar shape; AST JSON edited or generated by tooling that emits single children unwrapped; accessing a key with the wrong name so the value is undefined.","solutions":["Confirm the key name matches the parser's node field (typo yields undefined)","Align parser and interpreter versions so node shapes agree","Wrap single-child grammar variants before reading: Array.isArray(v) ? v : [v]","Inspect the attached node in the error to identify which construct produced the bad shape"],"exampleFix":"// before\nconst args = getArray(node, \"arguments\") // single node\n// after\nconst raw = node[\"arguments\"]\nconst args = getArray(node, Array.isArray(raw) ? \"arguments\" : \"argument\")","handlingStrategy":"type-guard","validationCode":"const child = node[key]\nif (!Array.isArray(child)) {\n  throw new Error(`Expected array at node.${key}, got ${child === undefined ? \"undefined\" : typeof child}`)\n}\ngetArray(node, key)","typeGuard":"const hasArrayField = (node: AstNode, key: string): boolean => Array.isArray(node[key])","tryCatchPattern":"try {\n  items = getArray(node, \"body\")\n} catch (e) {\n  if (e instanceof InterpreterRuntimeError && e.message.includes(\"to be an array\")) {\n    const v = node[\"body\"]\n    items = v === undefined ? [] : [v] // normalize single-child / absent variants\n  } else throw e\n}","preventionTips":["Match parser and interpreter versions; grammar shape changes break field types","Check the key name against the parser's node definitions (typos yield undefined)","Wrap single-child grammar variants in an array before interpretation","Add a snapshot test interpreting representative programs for each node kind"],"tags":["ast","interpreter","type-mismatch"],"backgroundTag":"malformed-ast-node","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}