github/copilot-sdk · error · ResponseError
negative_zero
negative_zero
Error message
${context.label} contains negative zero at ${path}; normalize it to 0 What it means
The strict JSON validator rejects -0 because JSON.stringify serializes it as "0", so a journaled -0 would silently come back as 0 after a session resume, breaking the library's lossless replay guarantee. The error includes the path to the offending value.
Solutions
- Locate the value via the error's `path` and normalize it: `Object.is(v, -0) ? 0 : v`.
- Add `+ value` or `value + 0` normalization at the factory boundary before returning journaled data.
- Fix the upstream arithmetic so signed zero is never produced (e.g. use Math.round(Math.abs(x)) * sign).
Example fix
// before
return { delta: Math.round(-0.4) }; // -0
// after
return { delta: Math.round(-0.4) + 0 }; // 0 Defensive patterns
Strategy: validation
Validate before calling
function normalizeNegativeZero(v) {
if (typeof v === "number") return Object.is(v, -0) ? 0 : v;
if (Array.isArray(v)) return v.map(normalizeNegativeZero);
if (v && typeof v === "object") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, normalizeNegativeZero(x)]));
return v;
} Type guard
const isNegativeZero = (v: unknown): boolean => Object.is(v, -0);
Try / catch
try {
session.runFactory(step);
} catch (e) {
if (e?.details?.category === "negative_zero") {
console.error(`Normalize -0 at ${e.details.path} to 0`);
} else throw e;
} Prevention
- Add `+ value` or `value + 0` when normalizing numbers near zero (Math.round, Math.sign).
- Include -0 checks in JSON boundary tests.
- Avoid negating potentially zero values without normalization.
When it happens
Trigger: Returning a factory result or step value equal to -0, typically produced by expressions like -0, 0 * -1, -1 % 0 === -0? (no, but -0 arises from Math.round(-0.4), Math.sign(-0), Object.freeze artifacts, or negating zero).
Common situations: Math.round(-0.4) yielding -0, Math.sign(-0), negating a zero computed elsewhere, deserializing numeric data that contains -0, and clone/copy helpers preserving the signed zero.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- non_finite_number
- unsupported_type
- cyclic_value
- unsupported_object
- Unexpected trailing content at position
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/0e85215425be347a.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/session.ts:2321
path
);
}
if (current === null || typeof current === "boolean" || typeof current === "string") {
return;
}
if (typeof current === "number") {
if (!Number.isFinite(current)) {
throw strictJsonValidationError(
context,
"non_finite_number",
`${context.label} contains a non-finite number at ${path}`,
path
);
}
// JSON serializes -0 as "0", so a journaled -0 would come back as 0
// after a resume and break the lossless replay guarantee.
if (Object.is(current, -0)) {
throw strictJsonValidationError(
context,
"negative_zero",
`${context.label} contains negative zero at ${path}; normalize it to 0`,
path
);
}
return;
}
if (
typeof current === "function" ||
typeof current === "symbol" ||
typeof current === "bigint"
) {
throw strictJsonValidationError(
context,
"unsupported_type",
`${context.label} contains a function, symbol, or BigInt at ${path}`,
pathView on GitHub (pinned to cd8cf15dc3)