{"record":{"id":"cedc5e3d456e9887","repo":"ruvnet/ruflo","slug":"undefined-array-member-at-path-i","errorCode":null,"errorMessage":"undefined array member at ${path}[${i}]","messagePattern":"undefined array member at (.+?)\\[(.+?)\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/flywheel-receipt.ts","lineNumber":157,"sourceCode":"  termVerification?: TermVerification[];\n  now?: number;\n  ttlMs?: number;\n  privateKeyPem?: string;\n  publicKeyPem?: string;\n  bootstrapIterations?: number;\n}\n\nfunction assertJsonValue(value: unknown, path = '$'): void {\n  if (value === null || typeof value === 'string' || typeof value === 'boolean') return;\n  if (typeof value === 'number') {\n    if (!Number.isFinite(value) || Object.is(value, -0)) {\n      throw new Error(`non-canonical number at ${path}`);\n    }\n    return;\n  }\n  if (Array.isArray(value)) {\n    value.forEach((v, i) => {\n      if (v === undefined) throw new Error(`undefined array member at ${path}[${i}]`);\n      assertJsonValue(v, `${path}[${i}]`);\n    });\n    return;\n  }\n  if (typeof value === 'object') {\n    for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n      if (child === undefined) throw new Error(`undefined property at ${path}.${key}`);\n      assertJsonValue(child, `${path}.${key}`);\n    }\n    return;\n  }\n  throw new Error(`unsupported JSON value at ${path}`);\n}\n\n/**\n * RFC-8785-compatible for the JSON domain accepted above: ECMAScript primitive\n * serialization plus recursively sorted UTF-16 property names.\n */","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/services/flywheel-receipt.ts#L139-L175","documentation":"Thrown by assertJsonValue() inside canonicalizeJcs() during RFC-8785 JCS-style canonicalization. JSON has no 'undefined' type, so an array element that is literally the JavaScript value `undefined` cannot be serialized canonically and would make the receipt hash non-reproducible. The ${path}[${i}] placeholder points at the exact offending location in the value tree (e.g. $.heldOutDeltas[2]).","triggerScenarios":"Calling createFlywheelReceipt(), canonicalizeJcs(), policyCandidateId(), or sha256Ref() with a candidatePolicy / heldOutDeltas / any nested object that contains an array slot holding `undefined` (e.g. arr[2] = undefined, or [1, , 3] sparse-array coercion, or a map/filter that left an undefined element).","commonSituations":"A candidatePolicy record built from partial config where an array field was conditionally assigned undefined instead of being omitted; heldOutDeltas produced by a pipeline that can yield NaN/undefined slots; objects deserialized then re-extended with undefined defaults.","solutions":["Sanitize arrays before receipt creation: arr.filter((x) => x !== undefined).","Replace undefined slots with null (a valid JSON type) only if the consuming code treats null semantically.","Delete the property/omit the element at the source so the array never carries undefined.","If the value comes from external/JSON input, parse with a reviver that drops undefined."],"exampleFix":"// before\nconst policy = { weights: [1, undefined, 3] };\ncreateFlywheelReceipt({ candidatePolicy: policy, /* ... */ });\n// after\nconst policy = { weights: [1, undefined, 3].filter((x) => x !== undefined) };\ncreateFlywheelReceipt({ candidatePolicy: policy, /* ... */ });","handlingStrategy":"validation","validationCode":"function sanitizeForCanonical<T>(value: T): T {\n  if (Array.isArray(value)) return value.filter((v) => v !== undefined).map(sanitizeForCanonical) as T;\n  if (value && typeof value === 'object') {\n    return Object.fromEntries(\n      Object.entries(value as Record<string, unknown>)\n        .filter(([, v]) => v !== undefined)\n        .map(([k, v]) => [k, sanitizeForCanonical(v)])\n    ) as T;\n  }\n  return value;\n}\n// run before createFlywheelReceipt / canonicalizeJcs:\nconst safe = sanitizeForCanonical(candidatePolicy);","typeGuard":"function hasNoUndefined(value: unknown): boolean {\n  if (value === undefined) return false;\n  if (Array.isArray(value)) return value.every(hasNoUndefined);\n  if (value && typeof value === 'object')\n    return Object.values(value).every(hasNoUndefined);\n  return true;\n}","tryCatchPattern":"try {\n  const ref = policyCandidateId(policy);\n} catch (e) {\n  if (e instanceof Error && /undefined array member/.test(e.message)) {\n    throw new Error(`candidatePolicy is not JSON-canonical: ${e.message}`);\n  }\n  throw e;\n}","preventionTips":["Build policy objects with conditional assignment, never { ...opts } where opts may have undefined values.","Run a recursive undefined-strip on any externally-sourced object before receipt hashing.","Add a unit test that asserts canonicalizeJcs succeeds on every policy your code produces."],"tags":["validation","serialization","json","canonicalization","receipt"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}