remix-run/remix · error · TypeError

mounts must include at least one entry

Error message

mounts must include at least one entry

What it means

A numeric `remix test` option received a value that doesn't parse as a number. `optionalNumber` trims and converts with `Number()` and rejects empty strings and NaN before the value reaches the test runner.

Source

Thrown at packages/assets/src/lib/asset-server.ts:1047

function resolveAssetServerOptions<transforms extends AssetRequestTransformMap>(
  options: AssetServerCreateOptions<transforms>,
): ResolvedAssetServerOptions<transforms> {
  let rootDir = normalizeFilePath(fs.realpathSync(path.resolve(options.rootDir ?? process.cwd())))
  let basePath = normalizeBasePath(options.basePath)
  let scriptOptions = options.scripts ?? {}
  let fingerprintOptions = normalizeFingerprintOptions({
    fingerprint: options.fingerprint,
    watch: options.watch,
  })
  let watchOptions = normalizeWatchOptions(options.watch)
  let hmrFactory = normalizeHmrFactory(options.hmr)
  let mounts = options.mounts ?? defaultMounts

  if (hmrFactory && watchOptions === null) {
    throw new TypeError('hmr requires watch mode')
  }
  if (Object.keys(mounts).length === 0) {
    throw new TypeError('mounts must include at least one entry')
  }
  return {
    allowFiles: options.allowFiles,
    allowPackages: options.allowPackages,
    basePath,
    buildId: fingerprintOptions.buildId,
    define: scriptOptions.define,
    denyFiles: options.denyFiles,
    external: scriptOptions.external ?? [],
    files: normalizeFilesOptions(options.files),
    fingerprintAssets: fingerprintOptions.enabled,
    hmr: hmrFactory,
    minify: options.minify ?? false,
    mounts,
    loaders: scriptOptions.loaders ?? [],
    onError: options.onError ?? defaultErrorHandler,
    rootDir,
    routes: compileRoutes(basePath, [

View on GitHub (pinned to 9696913134)

Solutions

  1. Pass a plain number: `--bail 2`
  2. Only include the flag when the variable is non-empty and numeric
  3. Strip units/commas before passing values

Example fix

# before
remix test --timeout "100ms"
# after
remix test --timeout 100
Defensive patterns

Strategy: validation

Validate before calling

function numericOrOmit(raw: string | undefined): string[] {
  if (raw === undefined || raw.trim() === '' || Number.isNaN(Number(raw))) return [];
  return [raw];
}
run(['remix','test', ...numericOrOmit(process.env.TEST_TIMEOUT)])

Type guard

function isNumericFlagValue(v: string): boolean {
  return v.trim() !== '' && !Number.isNaN(Number(v));
}

Prevention

When it happens

Trigger: Passing `--<number-flag> abc`, `--flag ""`, or `12abc` to `remix test`; `value.trim() === ''` or `Number.isNaN(Number(value))` triggers the throw for any numeric option routed through this helper.

Common situations: Empty shell variables expanding into flag values; values with units (`100ms`); localized formats with commas.

Understand the failure class

Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/640c304367bf4ccf. Report an issue: GitHub.