oxc-project/oxc · warning · OxcDiagnostic
Name "{name}" is reserved.
Error message
Name "{name}" is reserved. What it means
The base diagnostic of vue/no-reserved-component-names: 'Name "{name}" is reserved.' Naming a component after a reserved token (e.g. kebab-case reserved custom-element names or deprecated HTML elements from the rule's util lists VUE_RESERVED_KEBAB_CASE_ELEMENTS / VUE_RESERVED_DEPRECATED_HTML_ELEMENTS) makes Vue unable to resolve it reliably in templates, because the name collides with platform or reserved vocabulary. The rule reads the component's `name` option (and file/name registrations) in objects recognized as component definitions.
Source
Thrown at crates/oxc_linter/src/rules/vue/no_reserved_component_names.rs:25
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
utils::{
VUE_RESERVED_DEPRECATED_HTML_ELEMENTS, VUE_RESERVED_HTML_ELEMENTS,
VUE_RESERVED_KEBAB_CASE_ELEMENTS, VUE_RESERVED_SVG_ELEMENTS, VUE2_BUILTIN_COMPONENT_NAMES,
VUE3_BUILTIN_COMPONENT_NAMES_EXTRA, find_property,
is_vue_component_options_object_excluding_instance,
},
};
fn reserved_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Name \"{name}\" is reserved.")).with_label(span)
}
fn reserved_in_html_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Name \"{name}\" is reserved in HTML.")).with_label(span)
}
fn reserved_in_vue_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Name \"{name}\" is reserved in Vue.js.")).with_label(span)
}
fn reserved_in_vue3_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Name \"{name}\" is reserved in Vue.js 3.x.")).with_label(span)
}
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoReservedComponentNames {
/// Disallow Vue 2 built-in component names (e.g. `Transition`, `KeepAlive`).View on GitHub (pinned to e1e7af627c)
Solutions
- Rename the component to something outside the reserved kebab-case/deprecated lists.
- If the name is only used for recursion or devtools, a prefixed unique name (e.g. 'AppCustomLinks') works without behavior change.
- If you intentionally declare a custom element, use Vue's `is`/custom-element registration path instead of a component name collision.
- Re-run oxlint to verify.
Example fix
// before
export default {
name: 'custom-links', // reserved
// ...
}
// after
export default {
name: 'AppCustomLinks',
// ...
} Defensive patterns
Strategy: validation
Prevention
- Pick component names that are not custom-element-like kebab tags or deprecated element names.
- Prefix shared-library component names (App*, Ui*) to stay clear of reserved vocabulary.
- Run oxlint with the Vue preset when naming new components.
When it happens
Trigger: Registering or declaring a component whose name equals an entry from the reserved kebab-case / deprecated HTML element lists, e.g. `export default { name: 'custom-links' }` or a component named after a deprecated element.
Common situations: Naming utility components after custom-element-style tags; porting HTML snippets into components and keeping the tag name; shared component libraries that were never checked against the reserved lists.
Related errors
- Name "{name}" is reserved in Vue.js.
- Name "{name}" is reserved in Vue.js 3.x.
- Name "{name}" is reserved in HTML.
- `VirtualFree` failed during cleanup: {err}
- Key `{name}` is reserved.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/df0b47fec07879fd.
Report an issue: GitHub.