affaan-m/ECC · error · Error
Binary name must be a non-empty string
Error message
Binary name must be a non-empty string
What it means
Thrown by getExecCommand() when the `binary` argument is falsy or not a string. getExecCommand builds the package manager's exec command (npx / pnpm dlx / yarn dlx / bunx) for a given binary; this is the first guard ensuring the binary identifier is a usable string before the command is assembled.
Source
Thrown at scripts/lib/package-manager.js:332
return pm.config.devCmd;
default:
return `${pm.config.runCmd} ${script}`;
}
}
// Allowed characters in arguments: alphanumeric, whitespace, dashes, dots, slashes,
// equals, colons, commas, quotes, @. Rejects shell metacharacters like ; | & ` $ ( ) { } < > !
const SAFE_ARGS_REGEX = /^[@a-zA-Z0-9\s_./:=,'"*+-]+$/;
/**
* Get the command to execute a package binary
* @param {string} binary - Binary name (e.g., "prettier", "eslint")
* @param {string} args - Arguments to pass
* @throws {Error} If binary name or args contain unsafe characters
*/
function getExecCommand(binary, args = '', options = {}) {
if (!binary || typeof binary !== 'string') {
throw new Error('Binary name must be a non-empty string');
}
if (!SAFE_NAME_REGEX.test(binary)) {
throw new Error(`Binary name contains unsafe characters: ${binary}`);
}
if (args && typeof args === 'string' && !SAFE_ARGS_REGEX.test(args)) {
throw new Error(`Arguments contain unsafe characters: ${args}`);
}
const pm = getPackageManager(options);
return `${pm.config.execCmd} ${binary}${args ? ' ' + args : ''}`;
}
/**
* Interactive prompt for package manager selection
* Returns a message for Claude to show to user
*
* NOTE: Does NOT spawn child processes to check availability.
* Lists all supported PMs and shows how to configure preference.View on GitHub (pinned to 01e15490f0)
Solutions
- Pass a literal binary name: getExecCommand('prettier', '--write .', opts).
- Guard the lookup result: if (!binaryName) throw a clearer caller-side error before getExecCommand.
- Default to a known binary when the source is optional.
- Type-check values read from JSON config before forwarding.
Example fix
// before
const cmd = getExecCommand(tool.binName, args, opts); // binName undefined
// after
const binName = tool && tool.binName;
if (!binName) throw new Error(`No binary for tool ${tool && tool.id}`);
const cmd = getExecCommand(binName, args, opts); Defensive patterns
Strategy: type-guard
Validate before calling
if (!binary || typeof binary !== 'string') {
throw new Error('binary name is required');
}
getExecCommand(binary, args, opts); Type guard
function isBinaryName(value) {
return typeof value === 'string' && value.length > 0;
} Prevention
- Look up binary names from a fixed catalog before calling.
- Guard adapter lookups that may return undefined.
- Type-check values read from config files.
When it happens
Trigger: Calling getExecCommand(), getExecCommand(undefined), getExecCommand(''), getExecCommand(null), or getExecCommand(42). A caller deriving the binary name from a lookup that returns undefined for an unknown tool.
Common situations: A tool-runner that looks up a binary by alias and the alias is missing; a refactor that changes the binary parameter position; passing an object where a string was expected; a config-driven exec where the binary key is absent.
Related errors
- Script name must be a non-empty string
- Unknown package manager: ${pmName}
- Script name contains unsafe characters: ${script}
- Binary name contains unsafe characters: ${binary}
- Arguments contain unsafe characters: ${args}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/e39761b2c59eebb1.
Report an issue: GitHub.