{"record":{"id":"b4761cafe850dda9","repo":"different-ai/openwork","slug":"json-parse-expects-a-string","errorCode":null,"errorMessage":"JSON.parse expects a string.","messagePattern":"JSON\\.parse expects a string\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/stdlib/json.ts","lineNumber":30,"sourceCode":"  if (!jsonStatics.has(name)) throw new InterpreterRuntimeError(`JSON.${name} is not available in CodeMode.`, node)\n  switch (name) {\n    case \"stringify\": {\n      const replacer = args[1]\n      if (Array.isArray(replacer) || replacer instanceof CodeModeFunction) {\n        throw new InterpreterRuntimeError(\n          \"JSON.stringify replacers are not supported in CodeMode.\",\n          node,\n          \"UnsupportedSyntax\",\n          [supportedSyntaxMessage],\n        )\n      }\n      const space = args[2]\n      const indent = typeof space === \"number\" || typeof space === \"string\" ? space : undefined\n      return JSON.stringify(copyOut(copyIn(args[0], \"JSON.stringify value\")), null, indent)\n    }\n    case \"parse\": {\n      const text = args[0]\n      if (typeof text !== \"string\") throw new InterpreterRuntimeError(\"JSON.parse expects a string.\", node)\n      try {\n        return copyIn(JSON.parse(text), \"JSON.parse result\")\n      } catch (error) {\n        throw new InterpreterRuntimeError(\n          `JSON.parse received invalid JSON: ${error instanceof Error ? error.message : String(error)}`,\n          node,\n        ).as(\"SyntaxError\")\n      }\n    }\n  }\n  throw new InterpreterRuntimeError(`JSON.${name} is not available in CodeMode.`, node)\n}\n","sourceCodeStart":12,"sourceCodeEnd":43,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/stdlib/json.ts#L12-L43","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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.","solutions":["Ensure the argument is a string before calling JSON.parse; if you have an object, you do not need to parse it.","If the value may be a number/boolean that is already valid JSON, convert explicitly with String(x) first.","If the value can be undefined/null, check for it and provide a default or throw a domain-specific error."],"exampleFix":"// before\nconst data = JSON.parse(response.body)\n// after\nconst raw = typeof response.body === \"string\" ? response.body : JSON.stringify(response.body)\nconst data = JSON.parse(raw)","handlingStrategy":"type-guard","validationCode":"if (typeof raw !== \"string\") throw new TypeError(\"JSON.parse input must be a string, got \" + typeof raw)","typeGuard":"const isParseable = (v: unknown): v is string => typeof v === \"string\"","tryCatchPattern":"try { return JSON.parse(text) } catch (e) { if (e instanceof InterpreterRuntimeError) return fallbackValue; throw e }","preventionTips":["Check typeof before every JSON.parse call","Remember JSON.stringify(undefined) returns undefined, not a string — never feed its result directly into parse","Treat already-parsed objects as data, not as parse input"],"tags":["json","codemode","type-error","argument-validation"],"backgroundTag":"invalid-json-parse-input","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}