affaan-m/ECC · error · Error
ECC_PROJECT_DIR must be an absolute path within /workspace.
Error message
ECC_PROJECT_DIR must be an absolute path within /workspace.
What it means
The launch() function in the terminal-opener script probes whether the configured terminal (WezTerm) is installed and responsive before spawning it, by running `<terminal> --version`. If detectTerminalCapability() returns available=false (binary missing, probe threw, probe timed out with ETIMEDOUT, or the version probe exited non-zero), launch() throws a combined 'reason: action' message. The action field always tells you to install WezTerm and ensure it is on PATH.
Source
Thrown at docker/plugin-setup/resolve-project-dir.js:15
#!/usr/bin/env node
'use strict';
const path = require('path');
const WORKSPACE_ROOT = '/workspace';
function resolveProjectDir(candidate) {
if (
typeof candidate !== 'string'
|| !path.posix.isAbsolute(candidate)
|| /[\0\r\n]/.test(candidate)
) {
throw new Error('ECC_PROJECT_DIR must be an absolute path within /workspace.');
}
const resolved = path.posix.resolve(candidate);
if (resolved === WORKSPACE_ROOT || !resolved.startsWith(`${WORKSPACE_ROOT}/`)) {
throw new Error('ECC_PROJECT_DIR must be a child path within /workspace.');
}
return resolved;
}
function main() {
try {
process.stdout.write(`${resolveProjectDir(process.argv[2])}\n`);
} catch (error) {
process.stderr.write(`Error: ${error.message}\n`);
process.exitCode = 2;
}
}
View on GitHub (pinned to 01e15490f0)
Solutions
- Install WezTerm (e.g. brew install --cask wezterm on macOS, or the official package for your OS) and confirm `wezterm --version` works in the same shell that runs this script.
- Ensure the wezterm binary directory is on PATH for the Node process — check process.env.PATH inside the script and fix the launching shell/IDE environment.
- Call detectTerminalCapability(plan) yourself before launch() and branch on the returned reason/detail instead of letting launch() throw.
- If you injected a custom spawnSync via dependencies, verify your stub returns { status: 0, stdout: '...' } rather than erroring.
Example fix
// before
launch(plan); // throws if wezterm missing
// after
const cap = detectTerminalCapability(plan);
if (!cap.available) {
console.error(`Cannot launch: ${cap.reason} (${cap.detail}). ${cap.action}`);
process.exit(1);
}
const result = launch(plan); Defensive patterns
Strategy: validation
Validate before calling
// Call detectTerminalCapability yourself before launch() and branch on the result.
const cap = detectTerminalCapability(plan);
if (!cap.available) {
console.error(`Terminal unavailable: ${cap.reason} — ${cap.detail}`);
console.error(`Action: ${cap.action}`);
process.exit(1);
}
const result = launch(plan); Type guard
// Narrow a capability object before relying on it.
function isCapable(c) {
return c && c.available === true && typeof c.version === 'string';
}
if (!isCapable(cap)) { /* handle */ } Try / catch
try {
const result = launch(plan);
} catch (e) {
// e.message is `${reason}: ${action}` — surface both to the user.
console.error(`Terminal launch failed: ${e.message}`);
process.exitCode = 1;
} Prevention
- Ensure wezterm is installed and on PATH in every environment that runs this script (CI, dev, containers).
- Assert `wezterm --version` succeeds in your setup script before invoking the opener.
- Call detectTerminalCapability() first and degrade gracefully instead of letting launch() throw.
When it happens
Trigger: Calling launch(plan) when (a) plan.ok is false — the plan itself is invalid; (b) the wezterm binary is not on PATH so spawnSync throws or returns ENOENT (reason='not-installed'); (c) `wezterm --version` times out after SYNC_TIMEOUT_MS (reason='probe-failed'); (d) `wezterm --version` exits with a non-zero status (reason='probe-failed').
Common situations: WezTerm is not installed on a headless/CI machine; wezterm is installed but not on the PATH inherited by the Node process; a shell misconfiguration means the probe cannot find the binary; WezTerm is installed but crashes on `--version` due to a broken config or missing display.
Related errors
- ${command} ${args.join(' ')} failed: ${result.error.message}
- ${command} ${args.join(' ')} failed: ${result.error.message}
- ${command} ${args.join(' ')} failed: ${result.error.message}
- Failed to run gh: ${result.error.message}
- Codex CLI is not installed
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/bc6daa1c9e6aa703.
Report an issue: GitHub.