{"record":{"id":"f8de4e2a21919ce7","repo":"oven-sh/bun","slug":"missing-prefix-prefix","errorCode":null,"errorMessage":"Missing prefix ${prefix}","messagePattern":"Missing prefix (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/css/build-prefixes.js","lineNumber":553,"sourceCode":"    throw new Error(\"build-prefixes.js: could not find the Features bitflags! block in src/css/targets.rs\");\n  }\n  targets = targets.replace(re, lines);\n  fs.writeFileSync(\"src/css/targets.rs\", targets);\n  await rustfmt(\"src/css/targets.rs\");\n  console.log(\"wrote src/css/targets.rs (Features block)\");\n}\n\n// ─── prefixes.rs ──────────────────────────────────────────────────────────\n{\n  const variants = [...new Set([...p.keys()].flat().map(enumify))].sort();\n  const arms = [];\n  for (const [features, versions] of p) {\n    const pats = features.map(enumify).join(\"\\n            | \");\n    const body = [];\n    for (const [name, pfx] of Object.entries(versions)) {\n      const inner = [];\n      for (const [prefix, [min, max]] of Object.entries(pfx)) {\n        if (!prefixConst[prefix]) throw new Error(\"Missing prefix \" + prefix);\n        const add = `prefixes |= VendorPrefix::${prefixConst[prefix]};`;\n        if (min == null && max == null) {\n          inner.push(`                    let _ = version;\\n                    ${add}`);\n        } else {\n          let cond;\n          if (min == null) cond = `version <= ${max}`;\n          else if (max == null) cond = `version >= ${min}`;\n          else if (min === max) cond = `version == ${min}`;\n          else cond = `version >= ${min} && version <= ${max}`;\n          inner.push(`                    if ${cond} {\\n                        ${add}\\n                    }`);\n        }\n      }\n      body.push(`                if let Some(version) = browsers.${name} {\\n${inner.join(\"\\n\")}\\n                }`);\n    }\n    arms.push(`            ${pats} => {\\n${body.join(\"\\n\")}\\n            }`);\n  }\n\n  const flex = Object.entries(flexSpec)","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/css/build-prefixes.js#L535-L571","documentation":"While generating prefixes.rs, build-prefixes.js maps each prefix key from @mdn/browser-compat-data to a VendorPrefix variant via the hard-coded `prefixConst` table, which only contains webkit, moz, ms and o. A prefix key not in that table means the generated `VendorPrefix::<X>` would not compile, so the generator aborts with the unknown prefix name.","triggerScenarios":"Upgrading @mdn/browser-compat-data introduces a vendor prefix beyond webkit/moz/ms/o for some CSS feature, and the generator hits it while emitting version-gated prefix rules.","commonSituations":"Dependency bumps bring in exotic or legacy prefixes from newer browser-compat-data snapshots; a data patch adds an unmatched prefix spelling.","solutions":["Extend `prefixConst` at src/css/build-prefixes.js:504 with the missing key mapped to the correct VendorPrefix variant (e.g. prefixConst[\"missing\"] = \"MISSING\").","Ensure the Rust VendorPrefix enum actually has that variant — add it in the CSS crate if it is genuinely new.","If the prefix is junk data, filter it out where the `p` map is built instead of mapping it."],"exampleFix":"// before\nconst prefixConst = { webkit: \"WEBKIT\", moz: \"MOZ\", ms: \"MS\", o: \"O\" };\n\n// after\nconst prefixConst = { webkit: \"WEBKIT\", moz: \"MOZ\", ms: \"MS\", o: \"O\", wp: \"WP\" };","handlingStrategy":"validation","validationCode":"const prefixConst = { webkit: \"WEBKIT\", moz: \"MOZ\", ms: \"MS\", o: \"O\" };\nfor (const [features, versions] of p) {\n  for (const pfx of Object.values(versions)) {\n    for (const prefix of Object.keys(pfx)) {\n      if (!prefixConst[prefix]) throw new Error(`browser-compat-data has unmapped prefix \"${prefix}\" — extend prefixConst`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After every @mdn/browser-compat-data bump, dry-run build-prefixes.js in CI.","Keep prefixConst and the Rust VendorPrefix enum in sync; add variants deliberately, not opportunistically mid-generation."],"tags":["codegen","css","vendor-prefix","mdn-data"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}