{"record":{"id":"7f1fc995f29a4e38","repo":"affaan-m/ECC","slug":"fail-claudesetuperror-with-code-message-and-details","errorCode":null,"errorMessage":"(fail) ClaudeSetupError with code, message and details","messagePattern":"\\(fail\\) ClaudeSetupError with code, message and details","errorType":"exception","errorClass":"ClaudeSetupError","httpStatus":null,"severity":"error","filePath":"scripts/lib/claude-plugin-setup.js","lineNumber":53,"sourceCode":"    this.observedScopes = [...(details.observedScopes || [])];\n    this.recovery = [...(details.recovery || [])];\n  }\n\n  toJSON() {\n    return {\n      error: {\n        code: this.code,\n        message: this.message,\n        phase: this.phase,\n        observedScopes: [...this.observedScopes],\n        recovery: [...this.recovery],\n      },\n    };\n  }\n}\n\nfunction fail(code, message, details) {\n  throw new ClaudeSetupError(code, message, details);\n}\n\nfunction normalizeGitHubRepository(value) {\n  if (typeof value !== 'string') return null;\n  const normalized = value.trim().replace(/\\.git$/i, '').replace(/\\/+$/, '');\n  const match = normalized.match(/^([^/]+\\/[^/]+)$/);\n  return match ? match[1].toLowerCase() : null;\n}\n\nfunction normalizeMarketplaceRepository(marketplace) {\n  return marketplace?.source === 'github'\n    ? normalizeGitHubRepository(marketplace.repo)\n    : normalizeGitHubGitOrigin(marketplace?.url);\n}\n\nfunction isOfficialMarketplace(marketplace) {\n  if (!marketplace || marketplace.name !== OFFICIAL_MARKETPLACE_NAME) return false;\n  return normalizeMarketplaceRepository(marketplace) === OFFICIAL_MARKETPLACE_REPO;","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/claude-plugin-setup.js#L35-L71","documentation":"fail() is the central error constructor for claude-plugin-setup.js: it throws a ClaudeSetupError carrying a machine-readable code, human message, and details object. Every failure path in this module (JSON parsing, plugin/marketplace listing, git availability, running the claude CLI, reading settings) funnels through it, so all setup failures share one shape.","triggerScenarios":"Running the plugin setup flow when: claude --plugin/--marketplace list output isn't a JSON array (parseJsonArray), the plugin/marketplace list command fails (parsePluginList/parseMarketplaceList), git isn't installed (assertGitAvailable), `claude` exits non-zero (runClaude), or settings.json can't be read/parsed (readSettings).","commonSituations":"Claude Code CLI not installed or not on PATH; git missing in slim CI images; corrupted or hand-edited settings.json; the `claude` CLI output format changed across versions, breaking JSON parsing.","solutions":["Read error.code and error.details on the caught ClaudeSetupError — they identify the exact failing step and underlying stderr.","Install prerequisites: ensure `claude` and `git` are on PATH (assertGitAvailable fails with a git code otherwise).","If readSettings/parseJsonArray failed, fix or restore the malformed settings/marketplace JSON files named in details.","Update the Claude Code CLI if the output shape changed, then re-run setup."],"exampleFix":"// before\ntry { await setup(); } catch (e) { console.log(e.message); }\n// after\ntry { await setup(); } catch (e) {\n  if (e instanceof ClaudeSetupError) console.error(`[${e.code}]`, e.message, e.details);\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const { execSync } = require('child_process');\nfor (const bin of ['claude', 'git']) {\n  try { execSync(`${bin} --version`, { stdio: 'ignore' }); } catch { throw new Error(`${bin} is not installed/on PATH`); }\n}","typeGuard":"function isClaudeSetupError(e) { return e && typeof e.code === 'string' && typeof e.message === 'string' && e.details !== undefined; }","tryCatchPattern":"try { await runSetup(); } catch (e) {\n  if (isClaudeSetupError(e)) {\n    switch (e.code) { case 'git_unavailable': console.error('Install git'); break; default: console.error(e.code, e.message, e.details); }\n  } else throw e;\n}","preventionTips":["Install claude CLI and git before running plugin setup (use full images in CI, not slim ones)","Do not hand-edit settings.json; keep it valid JSON","Pin/keep the Claude Code CLI updated so output formats match expectations"],"tags":["setup","cli","plugin"],"backgroundTag":"missing-dependency","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"}