affaan-m/ECC · error · Error
Invalid ${label}: expected JSON-compatible data
Error message
Invalid ${label}: expected JSON-compatible data What it means
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.
Source
Thrown at scripts/lib/install-lifecycle.js:170
function parseJsonLikeValue(value, label) {
if (value === undefined) {
return undefined;
}
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (error) {
throw new Error(`Invalid ${label}: ${error.message}`);
}
}
if (value === null || Array.isArray(value) || isPlainObject(value) || typeof value === 'number' || typeof value === 'boolean') {
return cloneJsonValue(value);
}
throw new Error(`Invalid ${label}: expected JSON-compatible data`);
}
function getOperationTextContent(operation) {
const candidateKeys = ['renderedContent', 'content', 'managedContent', 'expectedContent', 'templateOutput'];
for (const key of candidateKeys) {
if (typeof operation[key] === 'string') {
return operation[key];
}
}
return null;
}
function getOperationJsonPayload(operation) {
const candidateKeys = ['mergePayload', 'managedPayload', 'payload', 'value', 'expectedValue'];
for (const key of candidateKeys) {View on GitHub (pinned to 01e15490f0)
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.
Example fix
// before
operation.mergePayload = new Map([['key', 'value']]);
// after
operation.mergePayload = Object.fromEntries(new Map([['key', 'value']]));
// or
operation.mergePayload = { key: 'value' }; Defensive patterns
Strategy: type-guard
Validate before calling
function isJsonCompatible(v) {
if (v === null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return true;
if (Array.isArray(v)) return v.every(isJsonCompatible);
if (v && typeof v === 'object') return Object.values(v).every(isJsonCompatible);
return false;
}
if (!isJsonCompatible(payload)) {
throw new Error(`${label} contains non-JSON values (function/symbol/instance)`);
} Type guard
function isJsonCompatible(v) {
if (v === null) return true;
if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') return false;
if (typeof v !== 'object') return typeof v !== 'undefined';
if (Array.isArray(v)) return v.every(isJsonCompatible);
return Object.values(v).every(isJsonCompatible);
} Try / catch
try {
return parseJsonLikeValue(value, label);
} catch (err) {
if (/expected JSON-compatible data/.test(err.message)) {
throw new Error(`${label} must be plain JSON data; got ${Object.prototype.toString.call(value)}`);
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid ${label}: ${error.message}
- Invalid ${label} at ${filePath}: expected a JSON object
- ECC_PROJECT_DIR must be a child path within /workspace.
- Unknown argument: ${arg}
- --json may only be provided once
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/02cc64179100fd4a.
Report an issue: GitHub.