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

  1. Pass a non-empty string script name, e.g. getRunCommand('test').
  2. Validate/require the argument before calling, surfacing a friendly CLI usage error.
  3. Default the value at the call site when a fallback makes sense, e.g. script || 'test'.
  4. 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

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


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)