remix-run/remix · error · TypeError

fingerprint.buildId must be a string

Error message

fingerprint.buildId must be a string

What it means

When the `fingerprint` option is enabled, it must carry a `buildId` string so the asset server can build content-hashed asset URLs. This error fires when fingerprinting is on but `fingerprint.buildId` is not a string.

Source

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

  fingerprint: AssetServerOptions['fingerprint']
  watch: AssetServerOptions['watch']
}):
  | {
      enabled: false
      buildId?: string
    }
  | {
      enabled: true
      buildId: string
    } {
  if (!options.fingerprint) {
    return {
      enabled: false,
    }
  }

  if (typeof options.fingerprint.buildId !== 'string') {
    throw new TypeError('fingerprint.buildId must be a string')
  }

  if (options.fingerprint.buildId.length === 0) {
    throw new TypeError('fingerprint.buildId must be a non-empty string')
  }

  if (options.watch !== false) {
    throw new TypeError('fingerprint cannot be used with watch mode')
  }

  return {
    enabled: true,
    buildId: options.fingerprint.buildId,
  }
}

function normalizeWatchOptions(
  options: AssetServerOptions['watch'],

View on GitHub (pinned to 9696913134)

Solutions

  1. Set `fingerprint: { enabled: true, buildId }` where `buildId` comes from your build output/manifest
  2. Ensure `buildId` is defined before constructing options (default it, e.g. from `process.env.BUILD_ID`)
  3. Disable fingerprinting (`fingerprint: false`) if you don't need hashed URLs

Example fix

// before
fingerprint: { enabled: true }
// after
fingerprint: { enabled: true, buildId: manifest.buildId }
Defensive patterns

Strategy: validation

Validate before calling

if (fingerprint?.enabled && typeof fingerprint.buildId !== 'string') {
  throw new Error('buildId is required when fingerprinting is enabled')
}

Type guard

function hasValidBuildId(f: unknown): f is { enabled: true; buildId: string } {
  return !!f && typeof f === 'object' && (f as any).enabled !== false && typeof (f as any).buildId === 'string' && (f as any).buildId.length > 0
}

Prevention

When it happens

Trigger: Passing `fingerprint: { enabled: true }` (or a truthy `fingerprint`) without `buildId`, or with `buildId: undefined`/non-string, to the asset server options.

Common situations: Enabling fingerprinting in production builds without wiring the build ID from the bundler; spreading a fingerprint config where `buildId` was dropped; forgetting that falsy-but-present `fingerprint` objects skip this branch only when disabled.

Related errors


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