affaan-m/ECC · error · Error
Invalid ${label}: ${error.message}
Error message
Invalid ${label}: ${error.message} What it means
Thrown by parseJsonLikeValue() in scripts/lib/install-lifecycle.js when the input value is a string that fails JSON.parse. The label identifies the operation field that held the bad string (e.g. 'merge-json.mergePayload').
Source
Thrown at scripts/lib/install-lifecycle.js:162
function cloneJsonValue(value) {
if (value === undefined) {
return undefined;
}
return JSON.parse(JSON.stringify(value));
}
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];
}
}View on GitHub (pinned to 01e15490f0)
Solutions
- Inspect the operation field named in the label; reproduce the JSON.parse in isolation.
- Switch single quotes to double quotes; remove trailing commas; quote object keys.
- If the field is meant to hold free text, change the operation to pass an already-parsed object, not a JSON string.
- Validate user input with a JSON schema before constructing the operation.
Example fix
// before
operation.mergePayload = "{ key: 'value' }"; // not JSON
// after
operation.mergePayload = JSON.stringify({ key: 'value' });
// or pass the object directly
operation.mergePayload = { key: 'value' }; Defensive patterns
Strategy: try-catch
Validate before calling
function isJsonString(s) {
if (typeof s !== 'string') return false;
try { JSON.parse(s); return true; } catch { return false; }
}
if (typeof value === 'string' && !isJsonString(value)) {
throw new Error(`${label} is not valid JSON: ${value.slice(0, 120)}`);
} Type guard
function isParsableJson(s) {
if (typeof s !== 'string') return false;
try { JSON.parse(s); return true; } catch { return false; }
} Try / catch
try {
return parseJsonLikeValue(value, label);
} catch (err) {
if (/Invalid .*:/.test(err.message) && typeof value === 'string') {
throw new Error(`${label} must be valid JSON. Got: ${value.slice(0, 120)}`);
}
throw err;
} Prevention
- Pass structured payloads as objects, not JSON strings, when possible.
- Validate user-provided --set values with JSON.parse before constructing operations.
- Add a schema check that flags malformed JSON strings before install runs.
When it happens
Trigger: parseJsonLikeValue(value, label) where typeof value === 'string' but JSON.parse throws. Called from getOperationJsonPayload / getOperationPreviousJson for fields like mergePayload, managedPayload, payload, value, previousValue, etc.
Common situations: Install operation carries a JSON payload as a malformed string (trailing comma, unquoted key, single quotes); template renderer emitted JS object literal syntax instead of JSON; user-supplied --set value was not valid JSON.
Related errors
- Failed to parse ${label} at ${filePath}: ${error.message}
- Invalid ${label}: expected JSON-compatible data
- gh ${args.join(' ')} returned invalid JSON: ${error.message}
- Malformed coordination JSON in body: ${error.message} — raw:
- Failed to load policy from ${resolvedPath}: ${error.message}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/953cb80de2c18c96.
Report an issue: GitHub.