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

  1. Open the registry entry named by `name` in the message and set `startCommand` to a non-empty command string (e.g. "npm run watch").
  2. Remove the `startCommand` key entirely if the entry has no custom start command, since validation only runs when the key is present.
  3. 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.
  4. 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

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


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)