oxc-project/oxc · error · OxcDiagnostic
`defineOptions` has been called multiple times.
Error message
`defineOptions` has been called multiple times.
What it means
Diagnostic from the oxlint rule `vue/valid-define-options`. The rule collects the span of every `defineOptions(...)` call in the program; when more than one call is found (`visitor.call_spans.len() > 1`), it reports this diagnostic on EVERY call site (both the first and subsequent calls get a label). The Vue compiler allows at most one `defineOptions` per component; a second call is a compile error in `@vitejs/plugin-vue` / vue-loader.
Source
Thrown at crates/oxc_linter/src/rules/vue/valid_define_options.rs:21
ast::{CallExpression, Expression, IdentifierReference, ObjectPropertyKind},
};
use oxc_ast_visit::{VisitJs, walk_js};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode, ast_util::variable_declaration_kind, context::LintContext,
frameworks::FrameworkOptions, rule::Rule,
};
fn referencing_locally_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineOptions` is referencing locally declared variables.")
.with_label(span)
}
fn multiple_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineOptions` has been called multiple times.").with_label(span)
}
fn not_defined_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Options are not defined.").with_label(span)
}
fn disallow_prop_diagnostic(span: Span, prop_name: &str, instead_macro: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"`defineOptions()` cannot be used to declare `{prop_name}`. Use `{instead_macro}()` instead."
))
.with_label(span)
}
fn type_args_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineOptions()` cannot accept type arguments.").with_label(span)
}
#[derive(Debug, Default, Clone)]View on GitHub (pinned to e1e7af627c)
Solutions
- Delete all but one `defineOptions` call and merge the option properties into the surviving object literal.
- If the duplicates differ, reconcile them (e.g. combine `name` and `inheritAttrs` into a single call) instead of keeping both.
- Search the file for `defineOptions(` to confirm only one call remains after the merge.
Example fix
// before
<script setup>
defineOptions({ name: 'A' })
defineOptions({ name: 'B', inheritAttrs: false })
</script>
// after
<script setup>
defineOptions({ name: 'B', inheritAttrs: false })
</script> Defensive patterns
Strategy: validation
Validate before calling
const setup = extractScriptSetup(src);
const count = (setup.match(/\bdefineOptions\s*\(/g) ?? []).length;
if (count > 1) throw new Error(`Expected one defineOptions call, found ${count}`); Prevention
- Codemods that insert defineOptions({ name }) should first grep the file for an existing call and merge into it.
- When merging SFCs, search for `defineOptions(` in both files and reconcile.
- Keep vue/valid-define-options enabled in CI.
When it happens
Trigger: Two or more `defineOptions(...)` calls in the same .vue program (VueSetup framework option enabled). Typical trigger: `defineOptions({ name: 'A' }); defineOptions({ name: 'B' })` inside one `<script setup>`, often produced by merging two components or pasting a snippet that already contains a `defineOptions` call.
Common situations: Merging two SFCs where each had its own `defineOptions({ name })`; copy-pasting a component template that includes `defineOptions({ inheritAttrs: false })`; codemods that insert `defineOptions({ name })` into files that already have one.
Related errors
- `defineOptions` is referencing locally declared variables.
- Options are not defined.
- `defineOptions()` cannot be used to declare `{prop_name}`. U
- `defineOptions()` cannot accept type arguments.
- `defineProps` has been called multiple times.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/8a7498eec0f676b1.
Report an issue: GitHub.