{"record":{"id":"cc9ab92d70403aaf","repo":"affaan-m/ECC","slug":"non-interactive-guided-install-requires-at-least-o","errorCode":null,"errorMessage":"Non-interactive guided install requires at least one --harness.","messagePattern":"Non-interactive guided install requires at least one --harness\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/install-guided.js","lineNumber":189,"sourceCode":"  return {\n    ...options,\n    harnesses: normalizedHarnesses,\n    claudeScope,\n    claudeHooks,\n    profile,\n  };\n}\n\nfunction selectedHarnessIds(options) {\n  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);","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/install-guided.js#L171-L207","documentation":"validateExecutionMode() rejects non-interactive runs that select no harnesses. When stdin is not a TTY the script cannot ask which harnesses to install, so an explicit --harness list (or --all-harnesses) is mandatory. Without it there is nothing to install, so the script aborts before doing any work.","triggerScenarios":"Running the guided install non-interactively (piped stdin, CI, `</dev/null`) without any --harness flag, so selectedHarnessIds(options) returns an empty array.","commonSituations":"CI pipelines invoking the installer without harness flags; redirecting stdin accidentally (e.g. `install < file`) forcing non-interactive mode; wrapper scripts that drop --harness flags when variables are empty.","solutions":["Add explicit --harness flags, e.g. --harness claude --harness codex.","Or pass --all-harnesses to select every harness non-interactively.","In CI, ensure the harness list variable is non-empty before invoking the script."],"exampleFix":"// before (non-interactive)\nnode scripts/install-guided.js --claude-scope project --claude-hooks standard --yes\n// after\nnode scripts/install-guided.js --harness claude --claude-scope project --claude-hooks standard --yes","handlingStrategy":"validation","validationCode":"if (!process.stdin.isTTY && harnessFlags.length === 0) { throw new Error('Non-interactive runs need --harness or --all-harnesses'); }","typeGuard":null,"tryCatchPattern":"try { await runInstall(args); } catch (e) { if (String(e.message).includes('requires at least one --harness')) { console.error('Add --harness <id> or --all-harnesses for non-interactive use'); process.exit(2); } throw e; }","preventionTips":["Always pass explicit --harness flags in CI and scripted contexts.","Avoid accidental stdin redirection that flips the installer into non-interactive mode.","Assert the harness list variable is non-empty before invoking."],"tags":["cli","non-interactive","missing-argument"],"backgroundTag":"missing-required-flag","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"}