oxc-project/oxc · error · OxcDiagnostic

Do not use `arguments.{method_name}`.

Error message

Do not use `arguments.{method_name}`.

What it means

Diagnostic from the oxlint rule `no-caller` (crates/oxc_linter/src/rules/eslint/no_caller.rs). It reports access to `arguments.caller` or `arguments.callee` (the message template says `arguments.{method_name}`). Both properties are deprecated, unstandardized, and restricted in ES5 strict mode — accessing them on strict-mode functions or their arguments objects throws a TypeError at runtime, and they block engine optimizations like inlining.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_caller.rs:9

use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

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

fn no_caller_diagnostic(span: Span, method_name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Do not use `arguments.{method_name}`."))
        .with_help("`caller`, `callee`, and `arguments` properties may not be accessed on strict mode functions or the arguments objects for calls to them.")
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow the use of `arguments.caller` or `arguments.callee`.
    ///
    /// ### Why is this bad?
    ///
    /// The use of `arguments.caller` and `arguments.callee` make several code
    /// optimizations impossible. They have been deprecated in JavaScript, and
    /// their use is forbidden while in strict mode.
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Give the function a name and recurse via that name instead of `arguments.callee`.
  2. Replace `arguments` entirely with a rest parameter (`function f(...args)`) so there is no arguments object to reach into.
  3. If you need the calling context, restructure to pass an explicit callback/context argument instead of reading `arguments.caller`.
  4. As a last resort for machine-generated legacy code, suppress with `// oxlint-disable-next-line no-caller`.

Example fix

// before
const factorial = function (n) {
  return n <= 1 ? 1 : n * arguments.callee(n - 1);
};

// after
const factorial = function fact(n) {
  return n <= 1 ? 1 : n * fact(n - 1);
};
Defensive patterns

Strategy: type-guard

Validate before calling

// Detect legacy callee/caller usage before lint/strict-mode runtime failures
const usesArgumentsIntrospection = /arguments\s*\.\s*(callee|caller)/.test(src);
if (usesArgumentsIntrospection) block('legacy arguments introspection found');

Try / catch

// If you must run untrusted legacy code that may touch arguments.caller:
try {
  legacy();
} catch (e) {
  if (e instanceof TypeError && /callee|caller/.test(e.message)) {
    // strict-mode access; route to the named-function rewrite
  } else throw e;
}

Prevention

When it happens

Trigger: A StaticMemberExpression whose object is the identifier `arguments` and whose property name is `caller` or `callee` — e.g. `arguments.callee()`, `const f = arguments.caller;` — including function expressions named via `arguments.callee` for recursion.

Common situations: Old recursive anonymous function expressions (pre-ES5 idiom `function() { ... arguments.callee ... }`); minified or transpiled legacy bundles re-linted with oxlint; code copied from old snippets into a strict-mode ESM file where the access would actually throw.

Related errors


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