different-ai/openwork · error · InterpreterRuntimeError

JSON.parse expects a string.

Error message

JSON.parse expects a string.

What it means

CodeMode's JSON.parse implementation only accepts a real string as its argument. Because the sandbox cannot safely coerce arbitrary values (objects, arrays, numbers) into JSON text, it refuses anything that is not typeof "string" and throws InterpreterRuntimeError. This mirrors the JS spec behavior of throwing on non-string input but with an explicit, clearer message.

Source

Thrown at packages/codemode/src/stdlib/json.ts:30

  if (!jsonStatics.has(name)) throw new InterpreterRuntimeError(`JSON.${name} is not available in CodeMode.`, node)
  switch (name) {
    case "stringify": {
      const replacer = args[1]
      if (Array.isArray(replacer) || replacer instanceof CodeModeFunction) {
        throw new InterpreterRuntimeError(
          "JSON.stringify replacers are not supported in CodeMode.",
          node,
          "UnsupportedSyntax",
          [supportedSyntaxMessage],
        )
      }
      const space = args[2]
      const indent = typeof space === "number" || typeof space === "string" ? space : undefined
      return JSON.stringify(copyOut(copyIn(args[0], "JSON.stringify value")), null, indent)
    }
    case "parse": {
      const text = args[0]
      if (typeof text !== "string") throw new InterpreterRuntimeError("JSON.parse expects a string.", node)
      try {
        return copyIn(JSON.parse(text), "JSON.parse result")
      } catch (error) {
        throw new InterpreterRuntimeError(
          `JSON.parse received invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
          node,
        ).as("SyntaxError")
      }
    }
  }
  throw new InterpreterRuntimeError(`JSON.${name} is not available in CodeMode.`, node)
}

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Ensure the argument is a string before calling JSON.parse; if you have an object, you do not need to parse it.
  2. If the value may be a number/boolean that is already valid JSON, convert explicitly with String(x) first.
  3. If the value can be undefined/null, check for it and provide a default or throw a domain-specific error.

Example fix

// before
const data = JSON.parse(response.body)
// after
const raw = typeof response.body === "string" ? response.body : JSON.stringify(response.body)
const data = JSON.parse(raw)
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof raw !== "string") throw new TypeError("JSON.parse input must be a string, got " + typeof raw)

Type guard

const isParseable = (v: unknown): v is string => typeof v === "string"

Try / catch

try { return JSON.parse(text) } catch (e) { if (e instanceof InterpreterRuntimeError) return fallbackValue; throw e }

Prevention

When it happens

Trigger: Calling JSON.parse(x) where x is an object, array, number, null, undefined, boolean, or the result of JSON.stringify on undefined — i.e. any value where typeof x !== "string".

Common situations: Double-stringification confusion: a developer calls JSON.parse(response.body) where the HTTP client already parsed the body into an object; passing a number that 'looks like' JSON (JSON.parse(42)); passing undefined because an upstream variable was never assigned.

Related errors


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