{"record":{"id":"f6beabb6de9a98b2","repo":"earendil-works/pi","slug":"protocol-json-values-must-not-contain-circular-ref","errorCode":null,"errorMessage":"Protocol JSON values must not contain circular references","messagePattern":"Protocol JSON values must not contain circular references","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/server/src/protocol.ts","lineNumber":149,"sourceCode":"\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(`${label} must be a non-empty string`);\n\treturn value;\n}\n\nfunction timestamp(value: number): number {\n\tif (!Number.isSafeInteger(value) || value < 0)\n\t\tthrow new TypeError(\"Protocol timestamps must be non-negative integers\");\n\treturn value;\n}\n\n/** Validate and copy a value from an execution boundary into the protocol's JSON-compatible subset. */\nexport function toProtocolJsonValue(value: unknown, seen = new Set<object>()): JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw new TypeError(\"Protocol JSON numbers must be finite\");\n\t\treturn value;\n\t}\n\tif (typeof value !== \"object\") throw new TypeError(`Unsupported protocol JSON value: ${typeof value}`);\n\tif (seen.has(value)) throw new TypeError(\"Protocol JSON values must not contain circular references\");\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n\t\tthrow new TypeError(\"Protocol JSON objects must be plain objects\");\n\t}\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => toProtocolJsonValue(entry, seen));\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) result[key] = toProtocolJsonValue(entry, seen);\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n/** Lossily sanitize diagnostic tool details that must not affect execution semantics. */\nexport function sanitizeProtocolDetails(value: unknown, seen = new Set<object>()): JsonValue | undefined {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/earendil-works/pi/blob/4af9d21d3b4d664e4a29fcabfec85171077248e3/packages/server/src/protocol.ts#L131-L167","documentation":"Error \"Protocol JSON values must not contain circular references\" thrown in earendil-works/pi.","triggerScenarios":"Thrown at packages/server/src/protocol.ts:149 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove circular references before serializing the value."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4af9d21d3b4d664e4a29fcabfec85171077248e3","analyzedAt":"2026-08-24T13:07:14.692Z","schemaVersion":2},"datasetVersion":"2026-08-24T17:17:21.512Z"}