different-ai/openwork · error · InterpreterRuntimeError

JSON.parse received invalid JSON: ${error instanceof Error ?

Error message

JSON.parse received invalid JSON: ${error instanceof Error ? error.message : String(error)}

What it means

When the string passed to JSON.parse is not valid JSON, the sandbox catches the underlying SyntaxError and rethrows it as an InterpreterRuntimeError whose message embeds the parser's own explanation, tagged with .as("SyntaxError") so downstream code can still treat it as a syntax error. The library does this to keep the error inside its interpreter error model while preserving the original diagnostic.

Source

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

      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. Fix the JSON text: validate it with a linter or JSON.parse in a try block in regular JS to see the exact fault.
  2. Inspect the embedded message after the colon — it names the position of the syntax fault.
  3. If input may be empty or partial, guard with a check like if (!text) before parsing.

Example fix

// before
const cfg = JSON.parse(partialChunk)
// after
if (!partialChunk.trim()) return null
const cfg = JSON.parse(partialChunk)
Defensive patterns

Strategy: try-catch

Validate before calling

const looksLikeJson = (s: string) => s.trim().length > 0 && /^[\[\{]/.test(s.trim()) || /^["\d\-tfn]/.test(s.trim())

Type guard

const isNonEmptyString = (v: unknown): v is string => typeof v === "string" && v.trim().length > 0

Try / catch

try { return JSON.parse(text) } catch (e) { if (e instanceof InterpreterRuntimeError && text.length === 0) return null; throw e }

Prevention

When it happens

Trigger: Calling JSON.parse(text) where text contains malformed JSON: trailing commas, single quotes instead of double quotes, unquoted keys, truncated payloads, or empty string.

Common situations: Parsing truncated streaming responses; parsing config snippets copy-pasted from JSON5/JS object literals (single quotes, comments); parsing an empty file; server returned an HTML error page instead of JSON.

Understand the failure class

Related errors


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