oxc-project/oxc · warning · OxcDiagnostic
Unexpected function expression.
Error message
Unexpected function expression.
What it means
Diagnostic from the oxlint `prefer-arrow-callback` rule. It fires when a function expression is passed as a callback (e.g. `arr.map(function (x) { ... })`) and an arrow function would work (prefer_arrow_callback.rs:26-30). By default named function expressions and callbacks that reference `this` (allowUnboundThis) are exempt, per the config in the same file.
Source
Thrown at crates/oxc_linter/src/rules/eslint/prefer_arrow_callback.rs:26
},
};
use oxc_ast_visit::Visit;
use oxc_codegen::{Context, Gen};
use oxc_diagnostics::OxcDiagnostic;
use oxc_ecmascript::{BoundNames, IsSimpleParameterList};
use oxc_macros::declare_oxc_lint;
use oxc_semantic::ScopeFlags;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode,
context::LintContext,
fixer::{RuleFix, RuleFixer},
rule::{DefaultRuleConfig, Rule},
};
fn prefer_arrow_callback_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected function expression.")
.with_help("Use an arrow function instead.")
.with_label(span)
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
struct PreferArrowCallbackConfig {
/// If this option is set to `true`, named function expressions are allowed.
allow_named_functions: bool,
/// If this option is set to `false`, function expressions that reference `this` are reported even when they are not bound to a `this` value.
allow_unbound_this: bool,
}
impl Default for PreferArrowCallbackConfig {
fn default() -> Self {
Self { allow_named_functions: false, allow_unbound_this: true }
}
}View on GitHub (pinned to e1e7af627c)
Solutions
- Replace the function expression with an arrow function: `function (x) { return x; }` becomes `(x) => x` (auto-fixable where safe).
- If the callback relies on its own `this` or `arguments`, keep `function` and add an inline disable, or pass an explicit thisArg and convert.
- Tune options: allowNamedFunctions for named helpers, allowUnboundThis (default) to skip this-using callbacks.
- Leave the rule on in CI and fix incrementally file by file.
Example fix
// before
const doubled = nums.map(function (n) { return n * 2; });
// after
const doubled = nums.map((n) => n * 2); Defensive patterns
Strategy: validation
Validate before calling
// .oxlintrc.json — tune exemptions before enabling broadly
{ "rules": { "prefer-arrow-callback": ["warn", { "allowNamedFunctions": false, "allowUnboundThis": true }] } } Prevention
- Default to arrow functions for callbacks; reserve `function` for this/arguments-dependent logic.
- Keep allowUnboundThis true (default) unless you specifically audit this-usage.
- Let `oxlint --fix` convert callbacks where semantics are unchanged.
When it happens
Trigger: Enable `prefer-arrow-callback` and pass an anonymous function expression to any callback position: `setTimeout(function () { ... })`, `[1,2].map(function (n) { return n * 2; })`. Setting allowNamedFunctions=false also flags `map(function double(n) {...})`; allowUnboundThis=false flags callbacks using `this` even unbound.
Common situations: ES5-era code being modernized; callbacks written before the project adopted ES6; teams enabling the option set to catch Vue/jQuery-style `this` usage; interop code where arrow functions change `this` binding and the rule still suggests them (false-positive looking cases with thisArg arguments).
Related errors
- Use Object destructuring.
- Use Array destructuring.
- Expected longform method syntax.
- Prefer `async`/`await` to the callback pattern
- Expected method{method_name_str} to have this.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/4d3b87d56ffb6531.
Report an issue: GitHub.