affaan-m/ECC · error
Arguments contain unsafe characters
Error message
Arguments contain unsafe characters: ${args} What it means
getExecCommand() validates its optional args string against SAFE_ARGS_REGEX after checking the binary name. This error is thrown when args is a non-empty string containing characters the library considers unsafe for command-line interpolation (quotes, semicolons, command substitution, unescaped specials). It guards the generated command `${execCmd} ${binary} ${args}` against shell injection.
Solutions
- Simplify args to plain flags and safe values ('--fix', '--check .') and remove quoting/metacharacters the regex rejects.
- Pass variable data through a supported option or config file instead of inline command-line values (e.g. put complex rules in a config file and pass '--config file').
- Inspect the offending args in the message and split: keep static flags in args, move dynamic values into validated inputs or files.
- If the value is legitimately needed and safe, escape it per the library's SAFE_ARGS_REGEX expectations, or contribute/extend the allowlist consciously.
Example fix
// before
getExecCommand('eslint', `--rule "${userRule}"`)
// after
// write the rule to a temp config file instead of inline quoting
getExecCommand('eslint', `--config ${safeConfigPath}`) Defensive patterns
Strategy: validation
Validate before calling
const SAFE_ARGS = /^[A-Za-z0-9 .,=_:\/@+-]*$/;
if (args && !SAFE_ARGS.test(args)) {
throw new Error(`Unsafe arguments: ${args}`);
}
getExecCommand(binary, args); Type guard
function isSafeArgsString(v) {
return v == null || (typeof v === 'string' && /^[A-Za-z0-9 .,=_:\/@+-]*$/.test(v));
} Try / catch
try {
const cmd = getExecCommand(binary, args);
} catch (e) {
if (String(e.message).startsWith('Arguments contain unsafe characters')) {
console.error(`Move dynamic values (rules, paths, messages) out of inline args: ${args}`);
} else throw e;
} Prevention
- Keep args to static flags; route dynamic values through config files or validated options.
- Never interpolate user text, commit messages, or regexes directly into args.
- Avoid chained commands ('&&', ';') — one tool invocation per call.
- Prefer long-form flags without quoting; complex values belong in files passed via --config/--flag-file.
When it happens
Trigger: Calling getExecCommand('eslint', args) where args contains disallowed characters — e.g. getExecCommand('eslint', "--rule '{x: y}'"), getExecCommand('jest', '--testPathPattern=$(whoami)'), getExecCommand('prettier', '--plugin a;b').
Common situations: Quoted flag values with spaces or single quotes (rules, regexes, commit messages) pasted into args; interpolating file lists, branch names, or user text into args; multi-command strings ('a && b'); Windows-vs-POSIX quoting differences causing flags to look unsafe.
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
- Binary name contains unsafe characters
- Script name contains unsafe characters
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/452a91bad16d3a15.
Report an issue: GitHub.
Appendix: 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 8321021c54)