No Catch-Parameter Reassignment

ID

javascript.catch_variable_reassigned

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

JavaScript

Tags

code-smell, suspicious-assignment

Description

Reports assignments to the parameter of a catch clause. After try {…} catch (err) {…}, writing err = something; inside the handler discards the original error reference, breaking diagnostics that relied on it (logging, rethrows, root-cause chains).

Property assignments such as err.detail = … are not reported — those mutate the caught object, which is sometimes intentional. Only the binding itself is protected.

Rationale

  • Loggers, stack-trace serializers, and error-reporting tools all expect err to point at the originally-thrown object. After reassignment, the cause is lost forever and the new value (often a string or a wrapper) replaces the chain.

  • If a wrapping pattern is desired, declare a separate binding (const wrapped = new Error(…​)) and rethrow that — this preserves the original via wrapped.cause.

  • Catch parameters are scoped to the handler. Reassigning them inside has no effect on outer code, so it cannot even be a side-channel — it is purely local damage.

// Bad
try {
  doWork();
} catch (err) {
  err = new Error("wrapped");   // root cause is gone forever
  log(err);
}

Remediation

Use a fresh binding (and cause to keep the original error intact) instead of overwriting err.

// Good
try {
  doWork();
} catch (err) {
  const wrapped = new Error("wrapped", { cause: err });
  throw wrapped;
}

References