oxc-project/oxc · error · OxcDiagnostic

Props are not defined.

Error message

Props are not defined.

What it means

Diagnostic from the oxlint rule `vue/valid-define-props`. The shared helper `check_define_macro_call_expression` returns `DefineMacroProblem::EventsNotDefined` when a `defineProps` call declares no props at all: no type parameter, no runtime argument, and no `props` property in a sibling plain `<script>` block's `export default {}` (checked via `has_default_exports_property(&ctx.other_file_hosts(), "props")`). An empty `defineProps()` is dead code at best and usually a migration leftover that silently breaks prop passing.

Source

Thrown at crates/oxc_linter/src/rules/vue/valid_define_props.rs:29

};

fn has_type_and_arguments_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`defineProps` has both a type-only emit and an argument.")
        .with_help("remove the argument for better type inference.")
        .with_label(span)
}

fn called_multiple_times(span: Span, second_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`defineProps` has been called multiple times.")
        .with_help("combine all `defineProps` calls into a single `defineProps` call.")
        .with_labels([
            span.label("`defineProps` is called here"),
            second_span.label("`defineProps` is called here too"),
        ])
}

fn events_not_defined(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Props are not defined.")
        .with_help("Define at least one prop in `defineProps`.")
        .with_label(span)
}

fn referencing_locally(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`defineProps` 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("Props are defined in both `defineProps` and `export default {}`.")
        .with_help("Remove `export default`.")
        .with_label(span)
}

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

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Declare the props you actually use: `defineProps({ msg: String })`, `defineProps(['msg'])`, or `defineProps<{ msg?: string }>()`.
  2. If the component truly takes no props, delete the `defineProps()` call.
  3. If props are intentionally declared in the Options API sibling block, keep `export default { props: {...} }` and remove the empty macro, or move the declaration into `defineProps`.

Example fix

// before
<script setup>
defineProps()
</script>

// after
<script setup>
defineProps({ msg: String })
</script>
Defensive patterns

Strategy: validation

Validate before calling

const hasExportDefaultProps = /export\s+default\s*\{[\s\S]*?\bprops\s*:/.test(src);
const bare = /\bdefineProps\s*\(\s*\)/.test(setup);
if (bare && !hasExportDefaultProps) {
  throw new Error('defineProps() declares nothing and no props exist in export default {}');
}

Prevention

When it happens

Trigger: A bare `defineProps()` (no type args, no arguments) in a component that also does not declare `props` inside a sibling `export default {}`. The pass tests confirm `defineProps()` is accepted only when the plain `<script>` block has `export default { props: { msg: String } }`; a standalone `defineProps()` in `<script setup>` fails.

Common situations: Scaffolding a component and leaving the macro empty 'for later'; removing props during a refactor but keeping the call; generators that always emit `defineProps()` regardless of need.

Related errors


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