{"record":{"id":"d380f4adf354852e","repo":"affaan-m/ECC","slug":"invalid-metadata-json-error-message","errorCode":null,"errorMessage":"Invalid --metadata-json: ${error.message}","messagePattern":"Invalid --metadata-json: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/work-items.js","lineNumber":129,"sourceCode":"    } else if (!arg.startsWith('-')) {\n      parsed.positionals.push(arg);\n    } else {\n      throw new Error(`Unknown argument: ${arg}`);\n    }\n  }\n\n  return parsed;\n}\n\nfunction parseMetadataJson(value) {\n  if (value === undefined || value === null) {\n    return null;\n  }\n\n  try {\n    return JSON.parse(value);\n  } catch (error) {\n    throw new Error(`Invalid --metadata-json: ${error.message}`);\n  }\n}\n\nfunction resolveWorkItemId(options) {\n  return options.id || options.positionals[0] || null;\n}\n\nfunction normalizeLimit(value) {\n  const parsed = Number.parseInt(value, 10);\n  if (!Number.isFinite(parsed) || parsed <= 0) {\n    throw new Error(`Invalid limit: ${value}`);\n  }\n  return parsed;\n}\n\nfunction runGhJson(args) {\n  const shimPath = process.env.ECC_GH_SHIM;\n  const command = shimPath ? process.execPath : 'gh';","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/work-items.js#L111-L147","documentation":"parseMetadataJson parses the --metadata-json option string with JSON.parse. On a SyntaxError it rethrows with the original parser message appended, so the developer can see exactly what the JSON parser objected to. A null/absent value returns null and does not throw.","triggerScenarios":"`--metadata-json \"{name: 1}\"` (unquoted keys), single quotes instead of double quotes, trailing commas, or a shell-mangled string where quotes were stripped, leaving invalid JSON for JSON.parse.","commonSituations":"Shell quoting problems — the most common cause: `--metadata-json '{\"a\":1}'` working on one shell but mangled on Windows cmd or through another layer of interpolation; hand-written JSON with JS-style syntax; empty string passed due to an unset variable.","solutions":["Read the appended error.message — it points at the exact JSON syntax problem","Validate the JSON in a linter/`node -e 'JSON.parse(...)'` before passing it","Use double quotes for keys and string values; no trailing commas","Fix shell quoting: wrap the whole JSON in single quotes on POSIX, escape carefully on Windows","Prefer passing the JSON via a file or environment variable when quoting gets complex"],"exampleFix":"// before\nnode scripts/work-items.js add --metadata-json \"{status: 'draft'}\"\n// after\nnode scripts/work-items.js add --metadata-json '{\"status\":\"draft\"}'","handlingStrategy":"validation","validationCode":"function isValidJsonString(s) {\n  if (typeof s !== 'string' || s.length === 0) return false;\n  try { JSON.parse(s); return true; } catch { return false; }\n}\n// before invoking:\nif (!isValidJsonString(metadataJson)) throw new Error('metadata-json is not valid JSON');","typeGuard":"function isJsonObject(value) {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}","tryCatchPattern":"try {\n  const payload = buildUpsertPayload(options);\n} catch (err) {\n  if (err.message.startsWith('Invalid --metadata-json:')) {\n    console.error('Fix the JSON syntax in --metadata-json (double-quoted keys, no trailing commas).');\n    process.exit(2);\n  }\n  throw err;\n}","preventionTips":["Validate JSON with a linter or JSON.parse before passing it on the CLI","Wrap JSON in single quotes on POSIX shells; mind Windows quoting differences","Build JSON programmatically with JSON.stringify instead of hand-writing it","For complex metadata, pass a file path or env var to avoid shell mangling"],"tags":["cli","json","validation"],"backgroundTag":"json-parse-error","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}