Skip to main content
interlace
Plugin: reliabilityRules

no-missing-error-context

Report a thrown value the code proves carries no message, or no stack trace when that is required.

Report a throw whose value the code proves carries no message (and, with requireStackTrace, one that is not an Error and so has no stack).

This rule is part of eslint-plugin-reliability.

Quick Summary

AspectDetails
SeverityError (code quality)
Auto-Fix❌ No
CategoryError-handling
Suggestions✅ Add a message, throw an Error instance

Rule Details

Whoever catches an error needs to know what went wrong. The rule reports a throw when the code itself proves that context is missing.

requireMessage (default true) reports a thrown value with no message:

  • a built-in Error constructor (Error, TypeError, RangeError, …, with or without new) given no argument or an empty string;
  • an empty string thrown as is, null, undefined;
  • an object literal with no message key.

A rethrown binding (throw err), a non-empty string or template, a const bound to one, an object literal with a message, a custom error class given an argument, and a subclass declared in the file whose constructor passes a message to super all carry one.

requireStackTrace (default false) also reports a thrown value the code proves is not an Error: a primitive, an object literal, null / undefined, or an instance of a class declared in the file that does not extend Error. Whether a file-declared class is an Error is read from its extends clause, never from whether its name ends in "Error".

Configuration

OptionTypeDefaultDescription
requireMessagebooleantrueReport thrown values with no message
requireStackTracebooleanfalseReport thrown values that are not Errors
ignoreInTestsbooleantrueSkip *.test.* / *.spec.* files

Examples

❌ Incorrect

throw new Error();
throw TypeError('');
throw { code: 'E_CACHE' };

// With { requireStackTrace: true }
throw 'cache read failed';
class CacheError {
  constructor(readonly detail: string) {}
}
throw new CacheError('miss'); // not an Error: no stack

✅ Correct

throw new Error('cache read failed');
throw new Error(`cache read failed for ${id}`);
throw { message: 'cache read failed', code: 'E_CACHE' };

class CacheMiss extends Error {
  constructor() {
    super('cache read failed');
  }
}
throw new CacheMiss();

try {
  load();
} catch (err) {
  throw err; // the original error keeps its message and stack
}

Configuration Examples

// eslint.config.mjs
export default [
  {
    rules: {
      'reliability/no-missing-error-context': ['error', { requireStackTrace: true }],
    },
  },
];

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Values the file cannot see

Why: a value that comes from another module, a parameter or an unresolved call carries no evidence in this file, and a rule that decides from structure stays silent rather than guess.

// ❌ NOT DETECTED - origin in another module
import { getValue } from './helpers';
processValue(getValue());

Mitigation: apply the same contract inside the helper, where the evidence is visible.

Use this rule

npm install -D oxlint-plugin-reliability
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-reliability"],  "rules": {    "reliability/no-missing-error-context": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-reliability'],    rules: {      'reliability/no-missing-error-context': 'error',    },  },});

oxlint-plugin-reliability re-exports eslint-plugin-reliability/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.