different-ai/openwork · error · InterpreterRuntimeError

Expected '${key}' to be an array.

Error message

Expected '${key}' to be an array.

What it means

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.

Source

Thrown at packages/codemode/src/interpreter/model.ts:168

    `Syntax '${kind}' is not supported in CodeMode. ${supportedSyntaxMessage}`,
    node,
    "UnsupportedSyntax",
    [supportedSyntaxMessage],
  )

export const isRecord = (value: unknown): value is Record<string, unknown> =>
  typeof value === "object" && value !== null

export const asNode = (value: unknown, context: string): AstNode => {
  if (!isRecord(value) || typeof value.type !== "string") {
    throw new InterpreterRuntimeError(`Invalid AST node while reading ${context}.`)
  }
  return value as AstNode
}

export const getArray = (node: AstNode, key: string): Array<unknown> => {
  const value = node[key]
  if (!Array.isArray(value)) throw new InterpreterRuntimeError(`Expected '${key}' to be an array.`, node)
  return value
}

export const getString = (node: AstNode, key: string): string => {
  const value = node[key]
  if (typeof value !== "string") throw new InterpreterRuntimeError(`Expected '${key}' to be a string.`, node)
  return value
}

export const getBoolean = (node: AstNode, key: string): boolean => {
  const value = node[key]
  if (typeof value !== "boolean") throw new InterpreterRuntimeError(`Expected '${key}' to be a boolean.`, node)
  return value
}

export const getOptionalNode = (node: AstNode, key: string): AstNode | undefined => {
  const value = node[key]
  if (value === undefined || value === null) return undefined

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Confirm the key name matches the parser's node field (typo yields undefined)
  2. Align parser and interpreter versions so node shapes agree
  3. Wrap single-child grammar variants before reading: Array.isArray(v) ? v : [v]
  4. Inspect the attached node in the error to identify which construct produced the bad shape

Example fix

// before
const args = getArray(node, "arguments") // single node
// after
const raw = node["arguments"]
const args = getArray(node, Array.isArray(raw) ? "arguments" : "argument")
Defensive patterns

Strategy: type-guard

Validate before calling

const child = node[key]
if (!Array.isArray(child)) {
  throw new Error(`Expected array at node.${key}, got ${child === undefined ? "undefined" : typeof child}`)
}
getArray(node, key)

Type guard

const hasArrayField = (node: AstNode, key: string): boolean => Array.isArray(node[key])

Try / catch

try {
  items = getArray(node, "body")
} catch (e) {
  if (e instanceof InterpreterRuntimeError && e.message.includes("to be an array")) {
    const v = node["body"]
    items = v === undefined ? [] : [v] // normalize single-child / absent variants
  } else throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/79cd88ff98f5f083. Report an issue: GitHub.