{"record":{"id":"02cc64179100fd4a","repo":"affaan-m/ECC","slug":"invalid-label-expected-json-compatible-data","errorCode":null,"errorMessage":"Invalid ${label}: expected JSON-compatible data","messagePattern":"Invalid (.+?): expected JSON-compatible data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-lifecycle.js","lineNumber":170,"sourceCode":"\nfunction parseJsonLikeValue(value, label) {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  if (typeof value === 'string') {\n    try {\n      return JSON.parse(value);\n    } catch (error) {\n      throw new Error(`Invalid ${label}: ${error.message}`);\n    }\n  }\n\n  if (value === null || Array.isArray(value) || isPlainObject(value) || typeof value === 'number' || typeof value === 'boolean') {\n    return cloneJsonValue(value);\n  }\n\n  throw new Error(`Invalid ${label}: expected JSON-compatible data`);\n}\n\nfunction getOperationTextContent(operation) {\n  const candidateKeys = ['renderedContent', 'content', 'managedContent', 'expectedContent', 'templateOutput'];\n\n  for (const key of candidateKeys) {\n    if (typeof operation[key] === 'string') {\n      return operation[key];\n    }\n  }\n\n  return null;\n}\n\nfunction getOperationJsonPayload(operation) {\n  const candidateKeys = ['mergePayload', 'managedPayload', 'payload', 'value', 'expectedValue'];\n\n  for (const key of candidateKeys) {","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-lifecycle.js#L152-L188","documentation":"Thrown by parseJsonLikeValue() when the input value is not undefined, not a string, and not one of the JSON-compatible types (null, array, plain object, number, boolean). This catches values like functions, symbols, class instances, or NaN that cannot survive JSON round-tripping.","triggerScenarios":"parseJsonLikeValue(value, label) where typeof value is 'function', 'symbol', 'bigint', or value is a class instance / Map / Set / Date without toJSON. None of the branches at install-lifecycle.js:158-167 match, so the final throw fires.","commonSituations":"Caller builds an operation from rich runtime objects (Map, Date, class instance) instead of plain data; a function reference leaked into a payload field; bigint returned from a BigInt-aggregate; NaN/undefined sneaks in via a number field.","solutions":["Convert non-JSON values before assigning: Date -> .toISOString(), Map -> Object.fromEntries(...), Set -> [...set], BigInt -> String(...).","Strip functions/symbols from the payload before calling parseJsonLikeValue.","Construct operation payloads as plain object literals with only JSON-compatible leaves.","Run JSON.parse(JSON.stringify(payload)) yourself first to surface the bad field."],"exampleFix":"// before\noperation.mergePayload = new Map([['key', 'value']]);\n\n// after\noperation.mergePayload = Object.fromEntries(new Map([['key', 'value']]));\n// or\noperation.mergePayload = { key: 'value' };","handlingStrategy":"type-guard","validationCode":"function isJsonCompatible(v) {\n  if (v === null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return true;\n  if (Array.isArray(v)) return v.every(isJsonCompatible);\n  if (v && typeof v === 'object') return Object.values(v).every(isJsonCompatible);\n  return false;\n}\nif (!isJsonCompatible(payload)) {\n  throw new Error(`${label} contains non-JSON values (function/symbol/instance)`);\n}","typeGuard":"function isJsonCompatible(v) {\n  if (v === null) return true;\n  if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') return false;\n  if (typeof v !== 'object') return typeof v !== 'undefined';\n  if (Array.isArray(v)) return v.every(isJsonCompatible);\n  return Object.values(v).every(isJsonCompatible);\n}","tryCatchPattern":"try {\n  return parseJsonLikeValue(value, label);\n} catch (err) {\n  if (/expected JSON-compatible data/.test(err.message)) {\n    throw new Error(`${label} must be plain JSON data; got ${Object.prototype.toString.call(value)}`);\n  }\n  throw err;\n}","preventionTips":["Construct operation payloads from plain object literals only.","Convert Date/Map/Set/BigInt at the boundary, before assignment.","Run JSON.parse(JSON.stringify(payload)) as a smoke test in dev builds."],"tags":["json","validation","install","operations"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}