oxc-project/oxc · warning

Do not assign to the exception parameter.

Error message

Do not assign to the exception parameter.

What it means

This diagnostic comes from the `no_ex_assign` rule in oxlint. It reports an assignment to the exception parameter of a `catch` block. After the assignment, the original error object is lost, and no other path leads to it. The rule collects the bound names of the catch parameter with `BoundNames`, so destructured names count too, and reports writes to them.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_ex_assign.rs:11

use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_ecmascript::BoundNames;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::AstNode;
use oxc_span::Span;

use crate::{context::LintContext, rule::Rule};

fn no_ex_assign_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Do not assign to the exception parameter.")
        .with_help("Remove the assignment to the exception parameter, or refactor the code to use a different variable.")
        .with_note("If code in a catch block assigns a value to the exception parameter, it becomes impossible to refer to the error. Since there is no alternative way to access to this data, assignment of the parameter is absolutely destructive.")
        .with_label(span.label("this assignment destroys access to the caught exception"))
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow reassigning exceptions in catch clauses.
    ///
    /// ### Why is this bad?
    ///
    /// If a catch clause in a try statement accidentally
    /// (or purposely) assigns another value to the exception parameter,
    /// it is impossible to refer to the error from that point on.

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Use a new variable: `const wrapped = new Error('context'); wrapped.cause = e;`.
  2. Rethrow with cause: `throw new Error('context', { cause: e });`.
  3. Suppress only when the value is provably unused after the write: `// oxlint-disable-next-line no-ex-assign`.

Example fix

// before
try {
  parse(raw);
} catch (e) {
  e = new Error('parse failed');
  throw e;
}

// after
try {
  parse(raw);
} catch (e) {
  throw new Error('parse failed', { cause: e });
}
Defensive patterns

Strategy: validation

Validate before calling

// warn on writes to a catch parameter (simple text heuristic)
if (/catch\s*\(\s*(?:[A-Za-z_$][\w$]*|\{[^}]*\})\s*\)[\s\S]{0,120}?\b[A-Za-z_$][\w$]*\s*=(?!=)/.test(src)) {
  console.warn('possible assignment to catch parameter');
}

Prevention

When it happens

Trigger: Inside a catch block: `catch (e) { e = new Error('wrapped'); }`, the destructured form `catch ({ message }) { message = 'x'; }`, or a compound write such as `e += info`. The report labels the assignment span.

Common situations: A developer tries to normalize or wrap the caught error in place. Old patterns reuse the catch variable as a scratch variable. A rename refactor makes the catch parameter collide with a nearby name by habit.

Related errors


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