affaan-m/ECC · error · Error

--cwd must be an absolute path.

Error message

--cwd must be an absolute path.

What it means

validateCwd requires the --cwd value to be an absolute path on the current platform; it checks both POSIX (path.isAbsolute) and Windows (path.win32.isAbsolute) forms. Relative paths are ambiguous once the terminal process spawns in an unrelated working directory, so the script rejects them. Pass an absolute directory to launch the terminal in.

Solutions

  1. Resolve the directory first: `node open-terminal.js --cwd "$(pwd)/project"` or in JS `path.resolve('myfolder')`.
  2. Use an absolute path with drive letter on Windows, e.g. `--cwd C:\\Users\\me\\project`.
  3. Have calling scripts always pass `path.resolve(cwd)` output.

Example fix

// before
node open-terminal.js --cwd ../myproject
// after
node open-terminal.js --cwd "$(cd ../myproject && pwd)"
Defensive patterns

Strategy: validation

Validate before calling

const path = require('path');
const isAbs = (v) => path.isAbsolute(v) || path.win32.isAbsolute(v);
if (!isAbs(cwd)) throw new Error('cwd must be absolute: ' + path.resolve(cwd));

Type guard

function isAbsoluteCrossPlatform(v) {
  return typeof v === 'string' && (require('path').isAbsolute(v) || require('path').win32.isAbsolute(v));
}

Try / catch

try {
  parseArgs(process.argv);
} catch (e) {
  if (/must be an absolute path/.test(e.message)) {
    console.error('Resolve with path.resolve() before passing --cwd');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `open-terminal.js --cwd .`, `--cwd ../project`, or `--cwd myfolder` instead of a resolved absolute path.

Common situations: Users habitually pass relative paths from the shell; scripts that don't call path.resolve before invoking; shell aliases that expand to relative directories.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/8da6c06e740c4951. Report an issue: GitHub.

Appendix: source

Thrown at skills/terminal-opener/scripts/open-terminal.js:48

Always pass the executable and arguments as separate entries after --.
Shell command strings are not accepted.
`;
}

function isAbsolutePath(value) {
  return path.isAbsolute(value) || path.win32.isAbsolute(value);
}

function validateTerminalName(value) {
  if (!/^[A-Za-z0-9][A-Za-z0-9_.-]*$/.test(value)) {
    throw new Error('Invalid terminal name; use a simple adapter name such as wezterm.');
  }
}

function validateCwd(value) {
  if (value.includes('\0')) throw new Error('--cwd must not contain a NUL byte.');
  if (!isAbsolutePath(value)) throw new Error('--cwd must be an absolute path.');
}

function validateExecutable(value) {
  if (!value || /[\0\r\n]/.test(value)) {
    throw new Error('Executable must be a non-empty argv entry without control bytes.');
  }

  const whitespaceIndex = value.search(/\s/);
  const separatorIndexes = [value.indexOf('/'), value.indexOf('\\')].filter(index => index >= 0);
  const firstSeparatorIndex = separatorIndexes.length > 0 ? Math.min(...separatorIndexes) : -1;
  const resemblesExecutablePath = isAbsolutePath(value)
    || (firstSeparatorIndex >= 0 && (whitespaceIndex < 0 || firstSeparatorIndex < whitespaceIndex));

  if (whitespaceIndex >= 0 && !resemblesExecutablePath) {
    throw new Error(
      'Executable must be one argv entry, not an interpolated shell command string.'
    );
  }

View on GitHub (pinned to 8321021c54)