oxc-project/oxc · warning · OxcDiagnostic

Key `{name}` is reserved.

Error message

Key `{name}` is reserved.

What it means

The vue/no-reserved-keys rule reports keys in component options that collide with Vue instance properties — the built-in list in the source starts with `$` (`$delete`, `$on`, `$once`, `$off`, `$emit`, `$mount`, `$forceUpdate`, `$nextTick`, `$destroy`). Vue proxies `$`-prefixed instance properties and methods, so declaring such a key in `props`/`data`/`computed`/`methods`/`setup` leads to shadowing or hard-to-debug lookup failures. Extra names can be added via the rule's `reserved` config array.

Source

Thrown at crates/oxc_linter/src/rules/vue/no_reserved_keys.rs:53

    "$refs",
    "$isServer",
    "$attrs",
    "$listeners",
    "$watch",
    "$set",
    "$delete",
    "$on",
    "$once",
    "$off",
    "$emit",
    "$mount",
    "$forceUpdate",
    "$nextTick",
    "$destroy",
];

fn reserved_key_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Key `{name}` is reserved.")).with_label(span)
}

fn starts_with_underscore_diagnostic(key: &str, group: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Key `{key}` is reserved in `{group}` group.")).with_label(span)
}

#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
struct NoReservedKeysConfig {
    /// Extra reserved key names to disallow, on top of the built-in list.
    reserved: Vec<CompactStr>,
    /// Extra component option groups to inspect, on top of the built-in
    /// `props` / `computed` / `data` / `asyncData` / `methods` / `setup`.
    groups: Vec<CompactStr>,
}

#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
pub struct NoReservedKeys(Box<NoReservedKeysConfig>);

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Rename the key to drop the `$` prefix (e.g. `$theme` -> `theme`).
  2. If the name came from your own `reserved` config, reconcile the config with the component.
  3. Keep `emit` calls on the instance (`this.$emit(...)`) rather than defining keys with `$` names.
  4. Re-run oxlint to verify.

Example fix

// before
export default {
  data() {
    return { $bus: null } // Key `$bus` is reserved.
  }
}

// after
export default {
  data() {
    return { bus: null }
  }
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Defining a `$`-prefixed key (or any name in your configured `reserved` list) inside the built-in groups `props` / `computed` / `data` / `asyncData` / `methods` / `setup`, or any group added via the rule's `groups` config.

Common situations: Styling/theming objects like `$theme` in data; methods mirroring the old events API (`$on`, `$emit`-style names); porting jQuery-era `$`-prefixed conventions into Vue options; teams extending the `reserved` list and hitting newly added entries.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/0eb0887d62f6090b. Report an issue: GitHub.