{"record":{"id":"ec45edaefd16ce85","repo":"github/copilot-sdk","slug":"nested-undefined","errorCode":"nested_undefined","errorMessage":"${context.label} contains nested undefined at ${path}","messagePattern":"(.+?) contains nested undefined at (.+?)","errorType":"validation","errorClass":"ResponseError","httpStatus":null,"severity":"error","filePath":"nodejs/src/session.ts","lineNumber":2299,"sourceCode":"    return new ResponseError(ErrorCodes.InternalError, message, {\n        code: context.code,\n        category,\n        path,\n    });\n}\n\nfunction assertStrictJson(\n    value: unknown,\n    context: StrictJsonValidationContext\n): asserts value is JsonValue | undefined {\n    const ancestors = new Set<object>();\n\n    const visit = (current: unknown, path: string, allowUndefined: boolean): void => {\n        if (current === undefined) {\n            if (allowUndefined) {\n                return;\n            }\n            throw strictJsonValidationError(\n                context,\n                \"nested_undefined\",\n                `${context.label} contains nested undefined at ${path}`,\n                path\n            );\n        }\n        if (current === null || typeof current === \"boolean\" || typeof current === \"string\") {\n            return;\n        }\n        if (typeof current === \"number\") {\n            if (!Number.isFinite(current)) {\n                throw strictJsonValidationError(\n                    context,\n                    \"non_finite_number\",\n                    `${context.label} contains a non-finite number at ${path}`,\n                    path\n                );\n            }","sourceCodeStart":2281,"sourceCodeEnd":2317,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/session.ts#L2281-L2317","documentation":"strictJsonValidationError is thrown by the strict JSON validation walker when a value destined for JSON serialization contains undefined at a nested path where undefined is not allowed. JSON.stringify silently drops undefined values, so this library fails fast instead of sending a silently-mangled payload. The error carries code=nested_undefined and the offending path.","triggerScenarios":"Passing an object to a session API validated by strict JSON validation (e.g. message payloads, tool arguments, or factory inputs) that contains an explicitly-undefined nested property, or an array hole / undefined element, at a path where allowUndefined is false.","commonSituations":"Building payloads by conditionally spreading fields where a variable is undefined; reading a missing config value into the payload; optional function parameters forwarded directly into the request object; sparse arrays.","solutions":["Read the error's path field to locate the offending property and ensure it is defined before the call, or delete the key entirely instead of leaving it undefined.","Use a sanitizer that strips undefined values recursively before calling the API.","Fix the source of the undefined value (missing config, unset variable, absent function argument).","If undefined is legitimately allowed at that spot, use the API variant/flag that permits undefined (allowUndefined) if one exists."],"exampleFix":"// before\nawait session.send({\n  prompt: userPrompt,\n  context: { filter: maybeFilter } // maybeFilter may be undefined\n});\n// after\nconst payload = { prompt: userPrompt, context: {} };\nif (maybeFilter !== undefined) {\n  payload.context.filter = maybeFilter;\n}\nawait session.send(payload);","handlingStrategy":"validation","validationCode":"function assertNoUndefined(value: unknown, path = 'root'): void {\n  if (value === undefined) throw new Error(`undefined at ${path}`);\n  if (Array.isArray(value)) value.forEach((v, i) => assertNoUndefined(v, `${path}[${i}]`));\n  else if (value && typeof value === 'object') {\n    for (const [k, v] of Object.entries(value)) assertNoUndefined(v, `${path}.${k}`);\n  }\n}\n// call assertNoUndefined(payload) before session.send(payload)","typeGuard":"function isJsonSafe(v: unknown): boolean {\n  try { JSON.stringify(v); return true; } catch { return false; }\n}\n// note: JSON.stringify hides undefined; pair with assertNoUndefined above","tryCatchPattern":"try {\n  await session.send(payload);\n} catch (error) {\n  if ((error as { code?: string }).code === 'nested_undefined') {\n    console.error('Payload has undefined at:', (error as { path?: string }).path);\n  } else {\n    throw error;\n  }\n}","preventionTips":["Delete optional keys instead of assigning undefined","Never forward optional function parameters straight into payloads","Run a deep undefined-strip (or the validator above) on payloads before sending","Enable strict validation early in dev to catch payload construction bugs"],"tags":["validation","json","undefined","strict-mode"],"backgroundTag":"schema-validation-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"}