oxc-project/oxc · error · OxcDiagnostic

Custom events are defined in both `defineEmits` and `export

Error message

Custom events are defined in both `defineEmits` and `export default {}`.

What it means

Emitted by run_once of the vue valid-define-emits rule (define_in_both) when custom events are declared both via the defineEmits macro and via the emits option in an export default {} block. Duplicating the declaration is redundant and can desynchronize the two lists.

Source

Thrown at crates/oxc_linter/src/rules/vue/valid_define_emits.rs:41

            span.label("`defineEmits` is called here"),
            second_span.label("`defineEmits` is called here too"),
        ])
}

fn events_not_defined(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Custom events are not defined.")
        .with_help("Define at least one event in `defineEmits`.")
        .with_label(span)
}

fn referencing_locally(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`defineEmits` is referencing locally declared variables.")
        .with_help("inline the variable or import it from another module.")
        .with_label(span)
}

fn define_in_both(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Custom events are defined in both `defineEmits` and `export default {}`.")
        .with_help("Remove `export default`.")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct ValidDefineEmits;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Enforce valid usage of the `defineEmits` compiler macro in Vue.
    ///
    /// This rule reports `defineEmits` compiler macros in the following cases:
    ///
    /// - `defineEmits` is referencing locally declared variables.
    /// - `defineEmits` has both a literal type and an argument. e.g. `defineEmits<(e: 'foo')=>void>(['bar'])`
    /// - `defineEmits` has been called multiple times.
    /// - Custom events are defined in both `defineEmits` and `export default {}`.

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Keep only the defineEmits macro declaration in <script setup> and remove the emits option from export default
  2. Or, in non-setup scripts, keep only the export default emits option and drop defineEmits
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/oxc_linter/src/rules/vue/valid_define_emits.rs:41 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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