{"record":{"id":"b70aa2f207ca3a41","repo":"github/copilot-sdk","slug":"unsupported-type","errorCode":"unsupported_type","errorMessage":"${context.label} contains a function, symbol, or BigInt at ${path}","messagePattern":"(.+?) contains a function, symbol, or BigInt at (.+?)","errorType":"validation","errorClass":"ResponseError","httpStatus":null,"severity":"error","filePath":"nodejs/src/session.ts","lineNumber":2335,"sourceCode":"            }\n            // JSON serializes -0 as \"0\", so a journaled -0 would come back as 0\n            // after a resume and break the lossless replay guarantee.\n            if (Object.is(current, -0)) {\n                throw strictJsonValidationError(\n                    context,\n                    \"negative_zero\",\n                    `${context.label} contains negative zero at ${path}; normalize it to 0`,\n                    path\n                );\n            }\n            return;\n        }\n        if (\n            typeof current === \"function\" ||\n            typeof current === \"symbol\" ||\n            typeof current === \"bigint\"\n        ) {\n            throw strictJsonValidationError(\n                context,\n                \"unsupported_type\",\n                `${context.label} contains a function, symbol, or BigInt at ${path}`,\n                path\n            );\n        }\n        if (typeof current !== \"object\") {\n            throw strictJsonValidationError(\n                context,\n                \"unsupported_type\",\n                `${context.label} contains a function, symbol, or BigInt at ${path}`,\n                path\n            );\n        }\n        if (ancestors.has(current)) {\n            throw strictJsonValidationError(\n                context,\n                \"cyclic_value\",","sourceCodeStart":2317,"sourceCodeEnd":2353,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/session.ts#L2317-L2353","documentation":"The strict JSON validator rejects functions, symbols, and BigInts in journaled factory results/steps because none of these have a JSON representation — JSON.stringify would silently drop or throw on them. Throwing up front with the offending path keeps journal data lossless and replayable.","triggerScenarios":"Returning a factory result or step containing a function value (a method, a callback, a class instance method copied onto a plain object), a symbol-keyed value assigned via computed keys, or a BigInt literal/operation result (123n, BigInt(x)).","commonSituations":"Accidentally spreading an object that includes methods (`{ ...someInstance }` keeps prototype methods on some shapes), using BigInt for IDs from a database driver, and attaching helper closures to result objects.","solutions":["Check the `path` in the error details and remove or convert the function/symbol/BigInt value at that location.","Convert BigInt to a string (or Number if safely representable) before journaling.","Build result objects explicitly instead of spreading class instances, so only JSON-safe fields are included."],"exampleFix":"// before\nreturn { id: 9007199254740993n, save: () => persist(state) };\n// after\nreturn { id: \"9007199254740993\" };","handlingStrategy":"validation","validationCode":"function assertJsonPrimitives(value, path = \"$\") {\n  if (typeof value === \"function\" || typeof value === \"symbol\" || typeof value === \"bigint\")\n    throw new Error(`Unsupported type at ${path}`);\n  if (Array.isArray(value)) value.forEach((v, i) => assertJsonPrimitives(v, `${path}[${i}]`));\n  else if (value && typeof value === \"object\")\n    for (const [k, v] of Object.entries(value)) assertJsonPrimitives(v, `${path}.${k}`);\n}","typeGuard":"const isJsonSerializable = (v: unknown): boolean =>\n  v === null || [\"string\", \"boolean\", \"number\"].includes(typeof v) ||\n  (Array.isArray(v) && v.every(isJsonSerializable)) ||\n  (v !== null && typeof v === \"object\" && Object.getPrototypeOf(v) === Object.prototype && Object.values(v).every(isJsonSerializable));","tryCatchPattern":"try {\n  session.runFactory(step);\n} catch (e) {\n  if (e?.details?.category === \"unsupported_type\") {\n    console.error(`Remove function/symbol/BigInt at ${e.details.path}`);\n  } else throw e;\n}","preventionTips":["Convert BigInt ids to strings at the boundary (e.g. right after DB reads).","Never spread class instances into journaled results; build plain objects explicitly.","Keep helper closures and callbacks out of result payloads."],"tags":["json","validation","bigint","factory-result"],"backgroundTag":"json-serialization-failed","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}