affaan-m/ECC · error · Error
${capability.reason}: ${capability.action}
Error message
${capability.reason}: ${capability.action} What it means
launch checks detectTerminalCapability(plan, spawnSync) before doing anything; when the detected terminal is not available, it throws `<reason>: <action>` — the reason explains why (binary missing, version too old) and the action tells the user what to do (install/configure another terminal).
Solutions
- Read the thrown reason/action text and install the suggested terminal or switch `terminal` in the tool's settings to an installed one.
- Run `open-terminal.js --detect` to see which terminals are available on this machine.
- Fix PATH so the terminal binary is resolvable (e.g. add its install dir in CI).
- Use --dry-run during setup to validate the plan without requiring the binary.
Example fix
// before // config: "terminal": "alacritty" (not installed) launch(plan); // throws 'alacritty not found: install alacritty or ...' // after // config: "terminal": "gnome-terminal" (detected as available) launch(plan);
Defensive patterns
Strategy: fallback
Validate before calling
const detected = JSON.parse(execSync('node open-terminal.js --detect --json').toString());
if (!detected.some(t => t.name === config.terminal && t.available)) {
config.terminal = detected.find(t => t.available)?.name;
} Try / catch
try {
const result = launch(plan);
} catch (err) {
if (/not available|not found|not installed/i.test(err.message)) {
console.error(`Terminal unavailable: ${err.message}\nRun --detect to list installed terminals, or install the suggested one.`);
} else throw err;
} Prevention
- Run --detect during setup and store an available terminal in config.
- Use --dry-run to validate the plan without needing the binary present.
- In CI/headless environments, expect no terminal emulator and skip launching rather than failing.
- Keep PATH consistent between interactive shells and automation.
When it happens
Trigger: Calling launch() (directly or via the CLI without --dry-run) when detectTerminalCapability returns { available: false } — typically because `spawnSync(command, ['--version'])` fails: terminal not installed, not on PATH, or unsupported flag set.
Common situations: Configured terminal (e.g. 'kitty', 'wezterm') not installed on the machine; running on WSL/SSH headless where no terminal emulator exists; PATH differs in CI vs interactive shell so the binary isn't found; stale config pointing at an old binary name.
Related errors
- discussion is not an Announcement
- discussion number is invalid
- ECC_ITO_CLI_EXECUTABLE does not point to a readable local…
- ECC_NASIKO_CLI_EXECUTABLE must be an absolute path.
- ENOENT
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/d22388ab673f4a24.
Report an issue: GitHub.
Appendix: source
Thrown at skills/terminal-opener/scripts/open-terminal.js:289
throw new Error('Terminal process did not start correctly.');
}
if (typeof child.once === 'function') {
child.once('error', error => {
onDetachedError(
new Error(`Unable to start ${command}: ${error.message}`, { cause: error })
);
});
}
child.unref();
}
function launch(plan, dependencies = {}) {
const spawnSyncImpl = dependencies.spawnSync || childProcess.spawnSync;
const spawnImpl = dependencies.spawn || childProcess.spawn;
const onDetachedError = dependencies.onDetachedError || reportDetachedError;
const capability = detectTerminalCapability(plan, spawnSyncImpl);
if (!capability.available) {
throw new Error(`${capability.reason}: ${capability.action}`);
}
if (plan.launchMode === 'recover') {
launchDetached(plan.command, plan.args, plan.cwd, spawnImpl, onDetachedError);
return { strategy: 'detached-recover', capability };
}
const muxResult = spawnSyncImpl(plan.command, plan.args, {
cwd: plan.cwd,
encoding: 'utf8',
killSignal: SPAWN_KILL_SIGNAL,
shell: false,
timeout: SYNC_TIMEOUT_MS,
});
if (!muxResult.error && muxResult.status === 0) {
return { strategy: 'mux', capability };
}
View on GitHub (pinned to 8321021c54)