affaan-m/ECC · error
Script name must be a non-empty string
Error message
Script name must be a non-empty string
What it means
getRunCommand first validates that the script argument is a non-empty string before any shell command is constructed. This guards the command-builder pipeline: null/undefined/empty script names cannot be mapped to a package-manager run command.
Solutions
- Pass a non-empty string script name, e.g. getRunCommand('test').
- Validate/require the argument before calling, surfacing a friendly CLI usage error.
- Default the value at the call site when a fallback makes sense, e.g. script || 'test'.
- Fix config parsing so numeric/undefined values are coerced or rejected earlier.
Example fix
// before
getRunCommand(argv.script); // argv.script undefined -> throws
// after
if (!argv.script || typeof argv.script !== 'string') {
process.exitCode = 1;
console.error('Usage: ecc run <script>');
} else {
getRunCommand(argv.script);
} Defensive patterns
Strategy: validation
Validate before calling
function requireScriptName(script) {
if (typeof script !== 'string' || script.length === 0) {
throw new Error('a non-empty script name is required, e.g. "test"');
}
return script;
} Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
const cmd = getRunCommand(script);
} catch (e) {
if (e.message === 'Script name must be a non-empty string') {
console.error('Usage: run <script> — e.g. run test');
process.exitCode = 1;
} else throw e;
} Prevention
- Require the script argument in your CLI parser before calling getRunCommand
- Coerce/validate config-derived script values to strings early
- Give sensible fallbacks (e.g. 'test') where optional
- Distinguish this error from the unsafe-characters error that follows it
When it happens
Trigger: Calling getRunCommand(''), getRunCommand(null), getRunCommand(undefined), or getRunCommand(123) — e.g. a parsed CLI arg that was never provided, or config value read as undefined.
Common situations: CLI invocation missing the script argument (e.g. `run` with no script name); destructured config field that is absent; programmatic callers passing non-string values.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- all overlays must be readable local files
- all takes must be readable local files
- Arguments must not contain NUL bytes.
- asset name must be a simple filename stem (letters, digits…
- At least one guided harness must be selected
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/3072b6badd2c1a88.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/package-manager.js:298
} catch (err) {
throw new Error(`Failed to save package manager config to ${configPath}: ${err.message}`);
}
return config;
}
// Allowed characters in script/binary names: alphanumeric, dash, underscore, dot, slash, @
// This prevents shell metacharacter injection while allowing scoped packages (e.g., @scope/pkg)
const SAFE_NAME_REGEX = /^[@a-zA-Z0-9_./-]+$/;
/**
* Get the command to run a script
* @param {string} script - Script name (e.g., "dev", "build", "test")
* @param {object} options - { projectDir }
* @throws {Error} If script name contains unsafe characters
*/
function getRunCommand(script, options = {}) {
if (!script || typeof script !== 'string') {
throw new Error('Script name must be a non-empty string');
}
if (!SAFE_NAME_REGEX.test(script)) {
throw new Error(`Script name contains unsafe characters: ${script}`);
}
const pm = getPackageManager(options);
switch (script) {
case 'install':
return pm.config.installCmd;
case 'test':
return pm.config.testCmd;
case 'build':
return pm.config.buildCmd;
case 'dev':
return pm.config.devCmd;
default:
return `${pm.config.runCmd} ${script}`;View on GitHub (pinned to 8321021c54)