{"record":{"id":"e39761b2c59eebb1","repo":"affaan-m/ECC","slug":"binary-name-must-be-a-non-empty-string","errorCode":null,"errorMessage":"Binary name must be a non-empty string","messagePattern":"Binary name must be a non-empty string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/package-manager.js","lineNumber":332,"sourceCode":"      return pm.config.devCmd;\n    default:\n      return `${pm.config.runCmd} ${script}`;\n  }\n}\n\n// Allowed characters in arguments: alphanumeric, whitespace, dashes, dots, slashes,\n// equals, colons, commas, quotes, @. Rejects shell metacharacters like ; | & ` $ ( ) { } < > !\nconst SAFE_ARGS_REGEX = /^[@a-zA-Z0-9\\s_./:=,'\"*+-]+$/;\n\n/**\n * Get the command to execute a package binary\n * @param {string} binary - Binary name (e.g., \"prettier\", \"eslint\")\n * @param {string} args - Arguments to pass\n * @throws {Error} If binary name or args contain unsafe characters\n */\nfunction getExecCommand(binary, args = '', options = {}) {\n  if (!binary || typeof binary !== 'string') {\n    throw new Error('Binary name must be a non-empty string');\n  }\n  if (!SAFE_NAME_REGEX.test(binary)) {\n    throw new Error(`Binary name contains unsafe characters: ${binary}`);\n  }\n  if (args && typeof args === 'string' && !SAFE_ARGS_REGEX.test(args)) {\n    throw new Error(`Arguments contain unsafe characters: ${args}`);\n  }\n\n  const pm = getPackageManager(options);\n  return `${pm.config.execCmd} ${binary}${args ? ' ' + args : ''}`;\n}\n\n/**\n * Interactive prompt for package manager selection\n * Returns a message for Claude to show to user\n *\n * NOTE: Does NOT spawn child processes to check availability.\n * Lists all supported PMs and shows how to configure preference.","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/package-manager.js#L314-L350","documentation":"getExecCommand() builds a command line to execute a binary through the detected package manager (e.g. 'npx prettier --check .'). The first guard rejects a binary parameter that is missing, not a string, or an empty string. The library requires a concrete binary name because it interpolates the value into a shell command and an empty name would produce a broken or dangerous command.","triggerScenarios":"Calling getExecCommand(''), getExecCommand(undefined), getExecCommand(null), getExecCommand(42), or any falsy/non-string first argument. Typically happens when the binary name is computed from config, an env var, or a lookup that returned nothing.","commonSituations":"Config file where the tool/binary field is blank or missing; a variable that is undefined because of a typo or failed lookup; refactors that changed the call signature and dropped the binary argument; passing options object as the first argument by mistake.","solutions":["Pass a concrete non-empty binary name string, e.g. getExecCommand('prettier', '--check .').","Log or inspect the value being passed right before the call to find where it becomes empty/undefined.","Fix the upstream source: default config value, correct env var (e.g. BINARY), or correct object property name.","Guard the call site: skip or throw a clearer domain error when the binary is unknown instead of forwarding an empty value."],"exampleFix":"// before\nconst binary = config.tools.formatter?.name; // undefined when key missing\nrun(getExecCommand(binary, args))\n// after\nconst binary = config.tools.formatter?.name;\nif (!binary) throw new Error('No formatter binary configured');\nrun(getExecCommand(binary, args))","handlingStrategy":"validation","validationCode":"if (typeof binary !== 'string' || binary.length === 0) {\n  throw new Error(`Binary must be a non-empty string, got: ${JSON.stringify(binary)}`);\n}\ngetExecCommand(binary, args);","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  const cmd = getExecCommand(binary, args);\n} catch (e) {\n  if (e.message === 'Binary name must be a non-empty string') {\n    console.error(`Binary lookup failed for config key; resolved to ${JSON.stringify(binary)}`);\n  } else throw e;\n}","preventionTips":["Provide default values for tool binaries in config so lookups never yield undefined.","Check config schema at load time (required fields present) before any exec calls.","Destructure carefully — a renamed config key silently produces undefined.","Log computed binary names once at startup to catch empties before they reach exec paths."],"tags":["validation","empty-argument","package-manager","argument-type"],"backgroundTag":"empty-required-field","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"}