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

  1. Read the thrown reason/action text and install the suggested terminal or switch `terminal` in the tool's settings to an installed one.
  2. Run `open-terminal.js --detect` to see which terminals are available on this machine.
  3. Fix PATH so the terminal binary is resolvable (e.g. add its install dir in CI).
  4. 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

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


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)