{"record":{"id":"3072b6badd2c1a88","repo":"affaan-m/ECC","slug":"script-name-must-be-a-non-empty-string","errorCode":null,"errorMessage":"Script name must be a non-empty string","messagePattern":"Script name must be a non-empty string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/package-manager.js","lineNumber":298,"sourceCode":"  } catch (err) {\n    throw new Error(`Failed to save package manager config to ${configPath}: ${err.message}`);\n  }\n  return config;\n}\n\n// Allowed characters in script/binary names: alphanumeric, dash, underscore, dot, slash, @\n// This prevents shell metacharacter injection while allowing scoped packages (e.g., @scope/pkg)\nconst SAFE_NAME_REGEX = /^[@a-zA-Z0-9_./-]+$/;\n\n/**\n * Get the command to run a script\n * @param {string} script - Script name (e.g., \"dev\", \"build\", \"test\")\n * @param {object} options - { projectDir }\n * @throws {Error} If script name contains unsafe characters\n */\nfunction getRunCommand(script, options = {}) {\n  if (!script || typeof script !== 'string') {\n    throw new Error('Script name must be a non-empty string');\n  }\n  if (!SAFE_NAME_REGEX.test(script)) {\n    throw new Error(`Script name contains unsafe characters: ${script}`);\n  }\n\n  const pm = getPackageManager(options);\n\n  switch (script) {\n    case 'install':\n      return pm.config.installCmd;\n    case 'test':\n      return pm.config.testCmd;\n    case 'build':\n      return pm.config.buildCmd;\n    case 'dev':\n      return pm.config.devCmd;\n    default:\n      return `${pm.config.runCmd} ${script}`;","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/package-manager.js#L280-L316","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ngetRunCommand(argv.script); // argv.script undefined -> throws\n// after\nif (!argv.script || typeof argv.script !== 'string') {\n  process.exitCode = 1;\n  console.error('Usage: ecc run <script>');\n} else {\n  getRunCommand(argv.script);\n}","handlingStrategy":"validation","validationCode":"function requireScriptName(script) {\n  if (typeof script !== 'string' || script.length === 0) {\n    throw new Error('a non-empty script name is required, e.g. \"test\"');\n  }\n  return script;\n}","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  const cmd = getRunCommand(script);\n} catch (e) {\n  if (e.message === 'Script name must be a non-empty string') {\n    console.error('Usage: run <script> — e.g. run test');\n    process.exitCode = 1;\n  } else throw e;\n}","preventionTips":["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"],"tags":["validation","argument","cli"],"backgroundTag":"missing-required-argument","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}