{"record":{"id":"9fcfda50c40ff87c","repo":"koala73/worldmonitor","slug":"name-startcommand-must-be-a-non-empty-string","errorCode":null,"errorMessage":"${name} startCommand must be a non-empty string","messagePattern":"(.+?) startCommand must be a non-empty string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/audit-railway-watch-paths.mjs","lineNumber":195,"sourceCode":"    throw new Error(`${name} dockerfile must be a non-empty string`);\n  }\n  if (entry.deployMode === 'dockerfile' && !hasOwn(entry, 'dockerfile')) {\n    throw new Error(`${name} deployMode dockerfile requires a dockerfile path`);\n  }\n  if (hasOwn(entry, 'watchPatterns')) {\n    if (!Array.isArray(entry.watchPatterns)\n      || entry.watchPatterns.some((pattern) => typeof pattern !== 'string')) {\n      throw new Error(`${name} watchPatterns must be an array of strings`);\n    }\n  }\n  if (hasOwn(entry, 'cronSchedule')\n    && entry.cronSchedule !== null\n    && typeof entry.cronSchedule !== 'string') {\n    throw new Error(`${name} cronSchedule must be a string or null`);\n  }\n  if (hasOwn(entry, 'startCommand')\n    && (typeof entry.startCommand !== 'string' || entry.startCommand.trim().length === 0)) {\n    throw new Error(`${name} startCommand must be a non-empty string`);\n  }\n  if (hasOwn(entry, 'requiredEnv')) {\n    if (!Array.isArray(entry.requiredEnv)) {\n      throw new Error(`${name} requiredEnv must be an array`);\n    }\n    for (const requirement of entry.requiredEnv) {\n      const alternatives = Array.isArray(requirement) ? requirement : [requirement];\n      if (alternatives.length === 0) {\n        throw new Error(`${name} requiredEnv contains an empty any-of group`);\n      }\n      for (const variable of alternatives) {\n        if (typeof variable !== 'string' || !/^[A-Z][A-Z0-9_]*$/.test(variable)) {\n          throw new Error(`${name} has invalid requiredEnv name ${JSON.stringify(variable)}`);\n        }\n      }\n    }\n  }\n  return entry;","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/scripts/audit-railway-watch-paths.mjs#L177-L213","documentation":"The Railway watch-paths audit validates each registry entry before use. When an entry declares a `startCommand`, it must be a string with at least one non-whitespace character. The script throws this error to fail fast on a malformed registry entry instead of silently treating a blank command as valid.","triggerScenarios":"Calling assertRegistryEntry with an entry object where `startCommand` is present but is not a string (e.g. a number, boolean, or object), or is a string that is empty or contains only whitespace (\"\", \"   \").","commonSituations":"A hand-edited or programmatically generated registry entry sets `startCommand: \"\"` as a placeholder, quoting issues in JSON/YAML collapse a command to whitespace, or a refactor changes the field's type without updating validation.","solutions":["Open the registry entry named by `name` in the message and set `startCommand` to a non-empty command string (e.g. \"npm run watch\").","Remove the `startCommand` key entirely if the entry has no custom start command, since validation only runs when the key is present.","Check the generator/template that produces the entry for a default of empty string and fix it to omit the key or supply a real command.","Trim user-supplied input at the source so whitespace-only values never reach the registry."],"exampleFix":"// before\n{ name: 'worker', startCommand: '' }\n// after\n{ name: 'worker', startCommand: 'npm run worker:start' }","handlingStrategy":"validation","validationCode":"if (entry.startCommand !== undefined && (typeof entry.startCommand !== 'string' || entry.startCommand.trim().length === 0)) {\n  throw new Error(`${entry.name}: startCommand must be a non-empty string`);\n}","typeGuard":"const hasStartCommand = (e) => typeof e.startCommand === 'string' && e.startCommand.trim().length > 0;","tryCatchPattern":"try {\n  assertRegistryEntry(name, entry);\n} catch (err) {\n  if (err.message.includes('startCommand must be a non-empty string')) {\n    console.error(`Registry entry ${name} has a blank startCommand; fix the registry file.`);\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Omit the startCommand key instead of setting it to an empty string when a command is not needed.","Validate registry JSON with a JSON schema (type: string, minLength: 1) in CI.","Trim user-supplied commands at input time.","Keep registry entries in one reviewed file so blank fields are caught in review."],"tags":["validation","config","nodejs"],"backgroundTag":"empty-required-field","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-15T18:17:12.389Z"}