affaan-m/ECC · error · Error

Executable must be a non-empty argv entry without control…

Error message

Executable must be a non-empty argv entry without control bytes.

What it means

validateExecutable requires the --executable value to be a non-empty single argv entry containing no control bytes (NUL, CR, LF). Empty strings and values with control characters cannot be safely passed as the program name when spawning the terminal, so they are rejected up front.

Solutions

  1. Provide a concrete executable name or path, e.g. `--executable wezterm` or `--executable /usr/bin/alacritty`.
  2. Strip control characters: `value.replace(/[\0\r\n]/g, '')` before invoking, or trim whitespace-only values.
  3. Fix the config/env source emitting the empty or binary-contaminated value.

Example fix

// before
const exe = config.executable ?? ''; // empty
node open-terminal.js --executable "$exe"
// after
const exe = config.executable?.trim();
if (exe) node open-terminal.js --executable "$exe"
Defensive patterns

Strategy: validation

Validate before calling

const ok = (v) => typeof v === 'string' && v.length > 0 && !/[\0\r\n]/.test(v);
if (!ok(exe)) throw new Error('executable must be non-empty without control bytes');

Type guard

function isCleanArgvEntry(v) {
  return typeof v === 'string' && v.length > 0 && !/[\0\r\n]/.test(v);
}

Try / catch

try {
  parseArgs(process.argv);
} catch (e) {
  if (/non-empty argv entry without control bytes/.test(e.message)) {
    console.error('Provide a concrete executable name/path with no control characters');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing `--executable ""`, a value containing a newline from a multi-line paste or config, or a string with an embedded NUL to open-terminal.js.

Common situations: Templated configs that interpolated an empty variable; heredoc/multi-line values that kept a trailing newline; programmatic callers concatenating buffers with control bytes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — 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/4388a6a5809a020e. Report an issue: GitHub.

Appendix: source

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

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.'
    );
  }
  if (!resemblesExecutablePath && /[;&|<>`$]/.test(value)) {
    throw new Error(
      'Executable must be one argv entry, not an interpolated shell command string.'
    );
  }

View on GitHub (pinned to 8321021c54)