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

  1. Add `super(message);` as the first statement of the constructor.
  2. Remove any `this.message = message` assignment — `super()` already sets it.
  3. 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

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


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