oxc-project/oxc · warning · OxcDiagnostic

Key ` ` is reserved in ` ` group.

Error message

Key `{key}` is reserved in `{group}` group.

What it means

The underscore variant of vue/no-reserved-keys: 'Key `{key}` is reserved in `{group}` group.' Vue treats `_`-prefixed properties as internal (not proxied on the instance), so a key starting with `_` declared in a group such as `props`, `data`, `computed`, `methods` or `setup` will not be reachable as `this.key` / in the template. The message names the offending group so you know exactly where the key lives.

Solutions

  1. Rename the key to remove the leading underscore.
  2. If the state really is private, keep it outside the proxied groups (module-scope variable or non-reactive closure state) rather than using a `_` name inside them.
  3. Check the rule's `groups` config if the report names a custom group you added.
  4. Re-run oxlint to confirm.

Example fix

// before
export default {
  data() {
    return { _cache: {} } // reserved in `data` group
  }
}

// after
const cache = {}; // module-scope, intentionally private
export default {
  data() {
    return { visibleCount: 0 }
  }
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Declaring an `_`-prefixed key in any built-in group (`props` / `computed` / `data` / `asyncData` / `methods` / `setup`) or a group listed in the rule's `groups` config, e.g. `data() { return { _internalFlag: true } }`.

Common situations: Marking 'private' state with a `_` prefix (a common convention from other languages); library components exposing `_`-prefixed props; Nuxt `asyncData` returning underscore keys that are then unreachable in the template.

Related errors


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

Appendix: source

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

    "$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>);

declare_oxc_lint!(
    /// ### What it does
    ///

View on GitHub (pinned to e1e7af627c)