affaan-m/ECC · error · Error
Arguments contain unsafe characters: ${args}
Error message
Arguments contain unsafe characters: ${args} What it means
Thrown by getExecCommand() when the `args` string is non-empty and fails SAFE_ARGS_REGEX = /^[@a-zA-Z0-9\s_./:=,'"*+-]+$/. This is a broader allowlist than the name regex (it permits whitespace and a set of CLI-friendly punctuation) but still rejects shell metacharacters like ; | & ` $ ( ) { } < > !.
Source
Thrown at scripts/lib/package-manager.js:338
// 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';
message += 'Supported package managers: ' + Object.keys(PACKAGE_MANAGERS).join(', ') + '\n';
message += '\nTo set your preferred package manager:\n';
message += ' - Global: Set CLAUDE_PACKAGE_MANAGER environment variable\n';View on GitHub (pinned to 01e15490f0)
Solutions
- Pass flags as a flat string using only allowed punctuation; avoid shell control operators.
- For complex argument vectors, build them as an array and join with spaces after validating each token.
- Reject args containing ; | & ` $ ( ) { } < > ! before calling.
- If a legitimate flag needs a disallowed character, wrap the operation in your own spawned process with an argv array instead of getExecCommand.
Example fix
// before
getExecCommand('eslint', '--fix && npm test', opts); // && rejected
// after
const lint = getExecCommand('eslint', '--fix .', opts);
const test = getRunCommand('test', opts);
// run lint, then test, as separate spawned processes Defensive patterns
Strategy: validation
Validate before calling
const SAFE_ARGS = /^[@a-zA-Z0-9\\s_./:=,'"*+-]+$/;
if (args && !SAFE_ARGS.test(args)) {
throw new Error(`Rejected args: ${args}`);
}
getExecCommand(binary, args, opts); Prevention
- Build args from an array of validated tokens rather than string concatenation.
- Reject any args containing ; | & ` $ ( ) { } < > ! before calling.
- Avoid shell control operators; chain commands via separate spawned processes.
When it happens
Trigger: Passing args containing command separators or substitution, e.g. getExecCommand('eslint', '.; rm -rf /'), getExecCommand('node', '-e "require(\"x\")" && cat x'), getExecCommand('curl', 'http://x | sh'), args with backticks, $(), or unbalanced quotes that include rejected chars.
Common situations: Forwarding a user-typed command line as args; passing glob patterns with characters the regex disallows (e.g. ? or !); embedding shell syntax to chain commands; args built from unsanitized env vars.
Related errors
- Script name contains unsafe characters: ${script}
- Binary name contains unsafe characters: ${binary}
- 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/452a91bad16d3a15.
Report an issue: GitHub.