{"record":{"id":"931687de7568000d","repo":"remix-run/remix","slug":"fingerprint-buildid-must-be-a-non-empty-string","errorCode":null,"errorMessage":"fingerprint.buildId must be a non-empty string","messagePattern":"fingerprint\\.buildId must be a non-empty string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/assets/src/lib/asset-server.ts","lineNumber":1168,"sourceCode":"      enabled: false\n      buildId?: string\n    }\n  | {\n      enabled: true\n      buildId: string\n    } {\n  if (!options.fingerprint) {\n    return {\n      enabled: false,\n    }\n  }\n\n  if (typeof options.fingerprint.buildId !== 'string') {\n    throw new TypeError('fingerprint.buildId must be a string')\n  }\n\n  if (options.fingerprint.buildId.length === 0) {\n    throw new TypeError('fingerprint.buildId must be a non-empty string')\n  }\n\n  if (options.watch !== false) {\n    throw new TypeError('fingerprint cannot be used with watch mode')\n  }\n\n  return {\n    enabled: true,\n    buildId: options.fingerprint.buildId,\n  }\n}\n\nfunction normalizeWatchOptions(\n  options: AssetServerOptions['watch'],\n): AssetServerWatchOptions | null {\n  if (options === false) return null\n  if (options == null || options === true) return {}\n  return options","sourceCodeStart":1150,"sourceCodeEnd":1186,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/assets/src/lib/asset-server.ts#L1150-L1186","documentation":"With fingerprinting enabled, `fingerprint.buildId` must be a non-empty string; an empty build id would produce broken asset URLs. This error fires when `buildId` is `''` (or an empty-after-trim string).","triggerScenarios":"Passing `fingerprint: { enabled: true, buildId: '' }`, typically from an unset build variable or a manifest field that hasn't been populated yet.","commonSituations":"`buildId: process.env.BUILD_ID || ''` patterns; reading a build id from a manifest file before it is generated; CI builds where the id is injected later than config construction.","solutions":["Ensure the build id is actually populated before creating the asset server (await manifest generation first)","Use a guaranteed fallback: `buildId: buildId ?? crypto.randomUUID()`","If fingerprinting is optional, gate it on the presence of a real build id"],"exampleFix":"// before\nfingerprint: { enabled: true, buildId: process.env.BUILD_ID ?? '' }\n// after\nlet buildId = process.env.BUILD_ID\nif (!buildId) throw new Error('BUILD_ID is required when fingerprinting is enabled')\nfingerprint: { enabled: true, buildId }","handlingStrategy":"validation","validationCode":"if (fingerprint?.enabled && fingerprint.buildId === '') {\n  throw new Error('BUILD_ID was empty; refusing to start with fingerprinting')\n}","typeGuard":"function isNonEmptyBuildId(id: unknown): id is string {\n  return typeof id === 'string' && id.length > 0\n}","tryCatchPattern":null,"preventionTips":["Never default buildId to an empty string","Assert env-provided ids are non-empty before constructing server options"],"tags":["config","fingerprinting","validation","build-id"],"backgroundTag":"config-type-validation","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}