swc-project/swc · error
unknown key: {k}
Error message
unknown key: {k} What it means
Runtime panic from swc's preset_env_base. `BrowserData` is a fixed, allocation-free struct map with a closed set of keys (chrome, chrome-android, firefox-android, opera-android, quest, react-native, and_chr, and_ff, op_mob, ie, edge, firefox, safari, node, ios, samsung, opera, android, electron, phantom, opera_mobile, rhino, deno, hermes, oculus, bun). `insert` linearly scans those keys and panics with `unknown key: {k}` for anything else — typically a browserslist query result naming an unmapped browser.
Source
Thrown at crates/preset_env_base/src/lib.rs:86
pub hermes: T,
#[serde(default)]
pub oculus: T,
#[serde(default)]
pub bun: T,
}
impl<T> BrowserData<T>
where
T: Default,
{
pub fn insert(&mut self, k: &str, v: T) -> T {
for (key, value) in self.iter_mut() {
if k == key {
return std::mem::replace(value, v);
}
}
panic!("unknown key: {k}")
}
}
/// A map of browser names to data for feature support in browser.
///
/// This type mainly stores `minimum version for each browsers with support for
/// a feature`.
pub type Versions = BrowserData<Option<Version>>;
impl BrowserData<Option<Version>> {
/// Returns true if all fields are [None].
pub fn is_any_target(&self) -> bool {
self.iter().all(|(_, v)| v.is_none())
}
/// Parses the value returned from `browserslist` as [Versions].
pub fn parse_versions(distribs: Vec<browserslist::Distrib>) -> Result<Self, Error> {
fn remap(key: &str) -> &str {View on GitHub (pinned to 5176682b65)
Solutions
- Narrow the browserslist query (e.g. explicit `chrome >= 90, firefox >= 100` instead of `defaults`/percentile queries)
- Pin the browserslist/caniuse database version so new browser ids cannot appear
- Map or filter the unsupported key before insert (see validation below)
- Upstream: extend BrowserData with the new browser field and its serde rename
Example fix
// before
let query = Query::from_str("> 0.5%", ...); // may include op_mini/kaios -> panic on insert
// after
let query = Query::from_str("chrome >= 90, firefox >= 100", ...); // only mapped keys Defensive patterns
Strategy: validation
Validate before calling
const KNOWN: &[&str] = &[
"chrome", "chrome-android", "firefox-android", "opera-android", "quest",
"react-native", "and_chr", "and_ff", "op_mob", "ie", "edge", "firefox",
"safari", "node", "ios", "samsung", "opera", "android", "electron",
"phantom", "opera_mobile", "rhino", "deno", "hermes", "oculus", "bun",
];
fn known_key(k: &str) -> bool {
KNOWN.contains(&k)
}
// before inserting a browserslist result:
let value = if known_key(name) {
data.insert(name, version)
} else {
// skip, log, or map the unsupported browser instead of panicking
log::warn!("ignoring unsupported browser target: {name}");
Default::default()
}; Type guard
fn is_supported_browser(name: &str) -> bool {
matches!(
name,
"chrome" | "chrome-android" | "firefox-android" | "opera-android" | "quest"
| "react-native" | "and_chr" | "and_ff" | "op_mob" | "ie" | "edge"
| "firefox" | "safari" | "node" | "ios" | "samsung" | "opera" | "android"
| "electron" | "phantom" | "opera_mobile" | "rhino" | "deno" | "hermes"
| "oculus" | "bun"
)
} Prevention
- Pin the browserslist/caniuse database version in CI to avoid new browser ids appearing overnight
- Prefer explicit browser lists over percentile/`defaults` queries that can pull in unmapped browsers
- When vendoring preset_env_base, keep the key-mapping table in query.rs in sync with BrowserData fields
When it happens
Trigger: A browserslist query (e.g. `defaults`, `> 0.5%`, `cover 95%`) resolves to a browser id that has no field, such as `op_mini`, `kaios`, `and_qq`, `and_uc`, or `baidu`; query.rs then calls `BrowserData::insert` with that name and panics.
Common situations: A browserslist/caniuse database update introduces or surfaces browser ids the static map does not know; using broad market-share queries in swc preset-env / parcel-css style tooling that pull in regional browsers.
Related errors
- Invalid attempt to iterate non-iterable instance. In order t
- Duplicated methods (${element.key}) can't be decorated.
- Decorators can't be placed on different accessors with for t
- Duplicated element (${element.key})
- Duplicated element (${elements[j].key})
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/b99616268cd46bc6.
Report an issue: GitHub.