oxc-project/oxc · warning · OxcDiagnostic
`button` elements must have an explicit `type` attribute.
Error message
`button` elements must have an explicit `type` attribute.
What it means
Diagnostic from the oxlint rule `react/button-has-type` (plugin `react`, category `restriction`). It fires on JSX `<button>` opening elements (only identifier-named elements; member/namespace names are skipped) that lack a `type` attribute (looked up case-insensitively), and on `createElement("button", ...)` calls where the second (props) argument is missing. The rule only runs for JSX sources (`should_run` checks `source_type().is_jsx()`). The HTML default for `type` is `"submit"`, which inside a `<form>` causes unexpected page reloads/submissions; the rule's stance is that the intent must be explicit even though all three values are allowed by default.
Source
Thrown at crates/oxc_linter/src/rules/react/button_has_type.rs:21
context::{ContextHost, LintContext},
rule::{DefaultRuleConfig, Rule},
utils::{get_prop_value, has_jsx_prop_ignore_case, is_create_element_call},
};
use oxc_ast::{
AstKind,
ast::{
Argument, Expression, JSXAttributeItem, JSXAttributeValue, JSXElementName,
ObjectPropertyKind,
},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use schemars::JsonSchema;
use serde::Deserialize;
fn missing_type_prop(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`button` elements must have an explicit `type` attribute.")
.with_help("Add a `type` attribute to the `button` element.")
.with_label(span)
}
fn invalid_type_prop(span: Span, allowed_types: &str) -> OxcDiagnostic {
OxcDiagnostic::warn("`button` elements must have a valid `type` attribute.")
.with_help(format!(
"Change the `type` attribute to one of the allowed values: {allowed_types}."
))
.with_label(span)
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct ButtonHasType {
/// If true, allow `type="button"`.
button: bool,
/// If true, allow `type="submit"`.View on GitHub (pinned to e1e7af627c)
Solutions
- Add an explicit `type`: `<button type="button">Save</button>` (or `type="submit"` / `type="reset"`)
- In `createElement` calls, pass a props object containing `type`
- If buttons appear outside forms and you accept the implicit default, still add `type` to satisfy the rule and document intent
Example fix
// before
<button onClick={save}>Save</button>
// after
<button type="button" onClick={save}>Save</button> Defensive patterns
Strategy: validation
Validate before calling
npx oxlint --react/button-has-type src/
Prevention
- Make `type` part of your button component's required props (forward it to the DOM element)
- Remember the implicit default is `type="submit"` inside forms
- Add explicit `type` when authoring; the rule fires even when props come from spread
When it happens
Trigger: `<button>Save</button>`; `<button {...props} />` with no explicit type attribute; `React.createElement('button')` without a props argument; any `<button>` whose attributes contain no `type`.
Common situations: Buttons inside forms triggering surprise submits; design-system button components forwarding props; JS-to-TSX conversions where attributes were dropped.
Related errors
- `button` elements must have a valid `type` attribute.
- `checked` should be used with either `onChange` or `readOnly
- Use either `checked` or `defaultChecked`, but not both.
- Component definition is missing display name.
- Invalid handler name: {handler_name}
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9d88a922de3e8f3b.
Report an issue: GitHub.