oven-sh/bun · error · Error

Missing prefix ${prefix}

Error message

Missing prefix ${prefix}

What it means

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.

Source

Thrown at src/css/build-prefixes.js:553

    throw new Error("build-prefixes.js: could not find the Features bitflags! block in src/css/targets.rs");
  }
  targets = targets.replace(re, lines);
  fs.writeFileSync("src/css/targets.rs", targets);
  await rustfmt("src/css/targets.rs");
  console.log("wrote src/css/targets.rs (Features block)");
}

// ─── prefixes.rs ──────────────────────────────────────────────────────────
{
  const variants = [...new Set([...p.keys()].flat().map(enumify))].sort();
  const arms = [];
  for (const [features, versions] of p) {
    const pats = features.map(enumify).join("\n            | ");
    const body = [];
    for (const [name, pfx] of Object.entries(versions)) {
      const inner = [];
      for (const [prefix, [min, max]] of Object.entries(pfx)) {
        if (!prefixConst[prefix]) throw new Error("Missing prefix " + prefix);
        const add = `prefixes |= VendorPrefix::${prefixConst[prefix]};`;
        if (min == null && max == null) {
          inner.push(`                    let _ = version;\n                    ${add}`);
        } else {
          let cond;
          if (min == null) cond = `version <= ${max}`;
          else if (max == null) cond = `version >= ${min}`;
          else if (min === max) cond = `version == ${min}`;
          else cond = `version >= ${min} && version <= ${max}`;
          inner.push(`                    if ${cond} {\n                        ${add}\n                    }`);
        }
      }
      body.push(`                if let Some(version) = browsers.${name} {\n${inner.join("\n")}\n                }`);
    }
    arms.push(`            ${pats} => {\n${body.join("\n")}\n            }`);
  }

  const flex = Object.entries(flexSpec)

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Extend `prefixConst` at src/css/build-prefixes.js:504 with the missing key mapped to the correct VendorPrefix variant (e.g. prefixConst["missing"] = "MISSING").
  2. Ensure the Rust VendorPrefix enum actually has that variant — add it in the CSS crate if it is genuinely new.
  3. If the prefix is junk data, filter it out where the `p` map is built instead of mapping it.

Example fix

// before
const prefixConst = { webkit: "WEBKIT", moz: "MOZ", ms: "MS", o: "O" };

// after
const prefixConst = { webkit: "WEBKIT", moz: "MOZ", ms: "MS", o: "O", wp: "WP" };
Defensive patterns

Strategy: validation

Validate before calling

const prefixConst = { webkit: "WEBKIT", moz: "MOZ", ms: "MS", o: "O" };
for (const [features, versions] of p) {
  for (const pfx of Object.values(versions)) {
    for (const prefix of Object.keys(pfx)) {
      if (!prefixConst[prefix]) throw new Error(`browser-compat-data has unmapped prefix "${prefix}" — extend prefixConst`);
    }
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: Dependency bumps bring in exotic or legacy prefixes from newer browser-compat-data snapshots; a data patch adds an unmatched prefix spelling.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/f8de4e2a21919ce7. Report an issue: GitHub.