koala73/worldmonitor · error · Error
${name} startCommand must be a non-empty string
Error message
${name} startCommand must be a non-empty string What it means
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.
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.
Example fix
// before
{ name: 'worker', startCommand: '' }
// after
{ name: 'worker', startCommand: 'npm run worker:start' } Defensive patterns
Strategy: validation
Validate before calling
if (entry.startCommand !== undefined && (typeof entry.startCommand !== 'string' || entry.startCommand.trim().length === 0)) {
throw new Error(`${entry.name}: startCommand must be a non-empty string`);
} Type guard
const hasStartCommand = (e) => typeof e.startCommand === 'string' && e.startCommand.trim().length > 0;
Try / catch
try {
assertRegistryEntry(name, entry);
} catch (err) {
if (err.message.includes('startCommand must be a non-empty string')) {
console.error(`Registry entry ${name} has a blank startCommand; fix the registry file.`);
process.exitCode = 1;
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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 ("", " ").
Common situations: 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.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- ${name} requiredEnv must be an array
- ${name} cronSchedule must be a string or null
- ${label} HTTP 400
- Could not resolve ${JSON.stringify(echoCountryInput(raw))} t
- INCOMPATIBLE_DELIVERY
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/9fcfda50c40ff87c.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/audit-railway-watch-paths.mjs:195
throw new Error(`${name} dockerfile must be a non-empty string`);
}
if (entry.deployMode === 'dockerfile' && !hasOwn(entry, 'dockerfile')) {
throw new Error(`${name} deployMode dockerfile requires a dockerfile path`);
}
if (hasOwn(entry, 'watchPatterns')) {
if (!Array.isArray(entry.watchPatterns)
|| entry.watchPatterns.some((pattern) => typeof pattern !== 'string')) {
throw new Error(`${name} watchPatterns must be an array of strings`);
}
}
if (hasOwn(entry, 'cronSchedule')
&& entry.cronSchedule !== null
&& typeof entry.cronSchedule !== 'string') {
throw new Error(`${name} cronSchedule must be a string or null`);
}
if (hasOwn(entry, 'startCommand')
&& (typeof entry.startCommand !== 'string' || entry.startCommand.trim().length === 0)) {
throw new Error(`${name} startCommand must be a non-empty string`);
}
if (hasOwn(entry, 'requiredEnv')) {
if (!Array.isArray(entry.requiredEnv)) {
throw new Error(`${name} requiredEnv must be an array`);
}
for (const requirement of entry.requiredEnv) {
const alternatives = Array.isArray(requirement) ? requirement : [requirement];
if (alternatives.length === 0) {
throw new Error(`${name} requiredEnv contains an empty any-of group`);
}
for (const variable of alternatives) {
if (typeof variable !== 'string' || !/^[A-Z][A-Z0-9_]*$/.test(variable)) {
throw new Error(`${name} has invalid requiredEnv name ${JSON.stringify(variable)}`);
}
}
}
}
return entry;View on GitHub (pinned to 7d06c8633d)