affaan-m/ECC · error · Error
Binary name contains unsafe characters: ${binary}
Error message
Binary name contains unsafe characters: ${binary} What it means
Thrown by getExecCommand() when the binary name fails SAFE_NAME_REGEX = /^[@a-zA-Z0-9_./-]+$/. Same injection guard as the script path: only alphanumeric, dash, underscore, dot, slash, and @ are allowed, supporting scoped packages like @scope/cli.
Source
Thrown at scripts/lib/package-manager.js:335
}
}
// 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.
*/
function getSelectionPrompt() {
let message = '[PackageManager] No package manager preference detected.\n';View on GitHub (pinned to 01e15490f0)
Solutions
- Validate the binary name against the same allowlist before calling.
- Restrict untrusted callers to a fixed catalog of known binaries.
- Strip disallowed characters and confirm the cleaned name is non-empty.
- Never derive a binary name by interpolating raw user input.
Example fix
// before
getExecCommand(userTool, args, opts); // userTool = 'eslint; rm -rf node_modules'
// after
const SAFE = /^[@a-zA-Z0-9_.\/-]+$/;
if (!SAFE.test(userTool)) throw new Error(`Invalid tool name: ${userTool}`);
getExecCommand(userTool, args, opts); Defensive patterns
Strategy: validation
Validate before calling
const SAFE_NAME = /^[@a-zA-Z0-9_.\/-]+$/;
if (!SAFE_NAME.test(binary)) {
throw new Error(`Rejected binary name: ${binary}`);
}
getExecCommand(binary, args, opts); Prevention
- Never derive a binary name from raw user input.
- Strip disallowed characters and re-validate the cleaned name.
- Prefer a plugin manifest declaring allowed binary names.
When it happens
Trigger: Passing a binary name with shell metacharacters or whitespace, e.g. getExecCommand('eslint; cat /etc/passwd'), getExecCommand('my tool'), getExecCommand('$(id)'), getExecCommand('prettier &').
Common situations: User-supplied tool name forwarded unsanitized; building a binary name by string concatenation with user input; a plugin system where a plugin declares a binary with disallowed characters; copy-paste introducing a stray space.
Related errors
- Script name contains unsafe characters: ${script}
- Arguments contain unsafe characters: ${args}
- Claude Code command contains characters that are unsafe for
- Unknown package manager: ${pmName}
- Script name must be a non-empty string
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/7431f17f769da684.
Report an issue: GitHub.