oxc-project/oxc · warning · OxcDiagnostic
Missing call to `super()` in constructor.
Error message
Missing call to `super()` in constructor.
What it means
Diagnostic from oxlint's `unicorn/custom-error-definition` rule (pending category). A custom error class — one extending a statically-named `*Error` superclass — has a constructor with a body but no `super(...)` call among its statements. Without `super()`, the built-in `Error` machinery never initializes `message` and `stack`, so thrown instances print as empty errors and behave incorrectly under inspection. The diagnostic points at the constructor body.
Source
Thrown at crates/oxc_linter/src/rules/unicorn/custom_error_definition.rs:20
AstKind,
ast::{
AssignmentTarget, Class, ClassElement, Expression, MethodDefinitionKind,
PropertyDefinition, Statement,
},
match_member_expression,
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, ast_util, context::LintContext, rule::Rule};
fn invalid_class_name_diagnostic(span: Span, expected: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Invalid class name, use `{expected}`.")).with_label(span)
}
fn missing_super_call_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Missing call to `super()` in constructor.").with_label(span)
}
fn invalid_name_property_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("The `name` property should be set to `{name}`.")).with_label(span)
}
fn pass_message_to_super_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Pass the error message to `super()` instead of setting `this.message`.")
.with_label(span)
}
fn invalid_export_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Exported error name should match error class").with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct CustomErrorDefinition;
View on GitHub (pinned to e1e7af627c)
Solutions
- Add `super(message);` as the first statement of the constructor.
- Remove any `this.message = message` assignment — `super()` already sets it.
- Verify with `new ApiError('x').stack` that message and stack are now populated.
Example fix
// before
class ApiError extends Error {
constructor(message) {
this.message = message;
this.name = 'ApiError';
}
}
// after
class ApiError extends Error {
constructor(message) {
super(message);
this.name = 'ApiError';
}
} Defensive patterns
Strategy: validation
Prevention
- Make `super(message)` the first statement of every custom error constructor.
- Never set `this.message` manually — the super call owns it.
- Smoke-test new error classes by logging `new MyError('x')` to confirm message and stack are populated.
When it happens
Trigger: `class ApiError extends Error { constructor(message) { this.message = message; } }` — any constructor of a valid custom error class whose statement list contains no `super(...)` call. Constructors without bodies (overload signatures only) are ignored.
Common situations: Custom error classes written by copying plain-class patterns; refactors where `super(message)` was accidentally deleted; minified/transpiled code paths that dropped the super call.
Related errors
- Invalid class name, use `{expected}`.
- The `name` property should be set to `{name}`.
- Pass a message to the {ctor_name:1} constructor.
- Error message should not be an empty string.
- Error message should be a string.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/07945e699e71a14b.
Report an issue: GitHub.