{"record":{"id":"189065ef98737c3a","repo":"affaan-m/ECC","slug":"non-interactive-and-json-mutations-require-yes","errorCode":null,"errorMessage":"Non-interactive and JSON mutations require --yes.","messagePattern":"Non-interactive and JSON mutations require --yes\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/install-guided.js","lineNumber":198,"sourceCode":"  if (options.allHarnesses) return normalizeHarnessSelection(['all']);\n  if (options.harnesses.length === 0) return [];\n  return normalizeHarnessSelection(options.harnesses);\n}\n\nfunction validateExecutionMode(options, interactive) {\n  const harnesses = selectedHarnessIds(options);\n  if (!interactive && harnesses.length === 0) {\n    throw new Error('Non-interactive guided install requires at least one --harness.');\n  }\n  const requiresExplicit = !interactive || options.json;\n  if (requiresExplicit && harnesses.includes('claude') && (!options.claudeScope || !options.claudeHooks)) {\n    throw new Error('Claude requires explicit --claude-scope and --claude-hooks choices in this mode.');\n  }\n  if (requiresExplicit && harnesses.includes('kimi') && !options.profile) {\n    throw new Error('Kimi requires an explicit --profile choice in this mode.');\n  }\n  if ((!interactive || options.json) && !options.yes && !options.dryRun) {\n    throw new Error('Non-interactive and JSON mutations require --yes.');\n  }\n}\n\nfunction printPlan(plan, output) {\n  output.write('\\nECC guided install preview\\n\\n');\n  output.write('Harness       Channel           Destination\\n');\n  for (const entry of plan.harnesses) {\n    const harness = getHarnessCapability(entry.id);\n    output.write(`${harness.label.padEnd(13)} ${entry.channel.padEnd(17)} ${harness.destination}\\n`);\n  }\n  if (plan.request.harnesses.includes('kimi')) {\n    output.write('\\nKimi note: ECC hooks are not configured; model, provider, and authentication settings are unchanged.\\n');\n  }\n}\n\nasync function confirmPlan(terminal, output) {\n  output.write('\\n');\n  const answer = await terminal.question('Apply ECC to these harnesses? [y/N]: ');","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/install-guided.js#L180-L216","documentation":"Any non-interactive or --json run that would actually mutate the install must confirm intent with --yes (or be a --dry-run preview). Without --yes and without --dry-run, the installer refuses to proceed to prevent accidental mutations in CI/automation.","triggerScenarios":"Running install-guided.js in CI with all the right selections but forgetting --yes, or using --json without --yes.","commonSituations":"CI pipelines, Docker builds, or scripted setups where the author omitted --yes expecting a prompt that cannot appear.","solutions":["Add --yes to confirm the mutation in non-interactive/JSON mode","Add --dry-run instead if you only want to preview the plan","Run interactively (with a TTY) so confirmation can be prompted"],"exampleFix":"// before\nnode scripts/install-guided.js --harness claude --claude-scope user --claude-hooks standard\n// after\nnode scripts/install-guided.js --harness claude --claude-scope user --claude-hooks standard --yes","handlingStrategy":"validation","validationCode":"const interactive = process.stdin.isTTY === true;\nconst mutatingNonInteractive = (!interactive || argv.includes('--json'));\nif (mutatingNonInteractive && !argv.includes('--yes') && !argv.includes('--dry-run')) {\n  throw new Error('Add --yes (or --dry-run) for non-interactive/JSON mutations');\n}","typeGuard":"function hasNonInteractiveConfirmation(argv) {\n  return argv.includes('--yes') || argv.includes('-y') || argv.includes('--dry-run');\n}","tryCatchPattern":"try { validateExecutionMode(options, interactive); }\ncatch (err) {\n  if (/require --yes/.test(err.message)) {\n    console.error(`${err.message} (or use --dry-run to preview)`);\n    process.exit(2);\n  }\n  throw err;\n}","preventionTips":["Always include --yes in CI install commands (or --dry-run for previews)","Gate mutation commands behind an explicit confirmation flag in wrappers","Document the --yes/--dry-run dichotomy in your runbook"],"tags":["cli","non-interactive","install-guided","safety-guard"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}