oxc-project/oxc · warning · OxcDiagnostic

Function `{name}` does not capture any variables from its pa

Error message

Function `{name}` does not capture any variables from its parent scope

What it means

Diagnostic from oxlint's `unicorn/consistent-function-scoping` rule. It reports functions declared inside another function that capture no variables from the enclosing scope — they can live at module scope instead, avoiding closure re-creation on every call and giving engines better optimization chances. This named variant is used when the function has a name; the diagnostic labels both the outer scope ('Outer scope where this function is defined') and the function itself, and the help text says to move it outward. Arrow functions are checked too unless `checkArrowFunctions: false`; React hook names are exempt.

Source

Thrown at crates/oxc_linter/src/rules/unicorn/consistent_function_scoping.rs:30

    ast_util::{get_function_like_declaration, is_node_call_like_argument, outermost_paren_parent},
    context::LintContext,
    rule::{DefaultRuleConfig, Rule},
    utils::is_react_hook,
};

fn consistent_function_scoping(
    fn_span: Span,
    parent_scope_span: Option<Span>,
    parent_scope_kind: Option<&'static str>,
    function_name: Option<&str>,
) -> OxcDiagnostic {
    let function_label = if let Some(name) = function_name {
        format!("Function `{name}` does not capture any variables from its parent scope")
    } else {
        "This function does not use any variables from its parent scope".into()
    };

    let d = OxcDiagnostic::warn(function_label).with_help(match function_name {
        Some(name) => {
            format!("Move `{name}` to the outer scope to avoid recreating it on every call.")
        }
        None => {
            "Move this function to the outer scope to avoid recreating it on every call.".into()
        }
    });

    match parent_scope_span {
        Some(parent) => d.with_labels([
            parent.label("Outer scope where this function is defined"),
            fn_span.primary_label(if let Some(parent_scope_kind) = parent_scope_kind {
                format!(
                    "This function does not use any variables from the parent {parent_scope_kind}"
                )
            } else {
                "This function does not use any variables from here".into()
            }),

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Hoist the named function to module scope, passing anything it needs as parameters.
  2. If it must stay local, make the dependency explicit by actually referencing an outer variable, then re-run.
  3. Reduce noise from arrows by configuring `checkArrowFunctions: false` in .oxlintrc.json.
  4. Disable the rule inline for deliberate cases (e.g. functions kept local for readability in tests).

Example fix

// before
export function doFoo(foo) {
  function doBar(bar) {
    return bar === 'bar';
  }
  return doBar;
}
// after
function doBar(bar) {
  return bar === 'bar';
}

export function doFoo(foo) {
  return doBar;
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json — tune the rule before enabling on arrow-heavy code
{
  "rules": {
    "unicorn/consistent-function-scoping": ["warn", { "checkArrowFunctions": false }]
  }
}

Prevention

When it happens

Trigger: A named inner function (or const-assigned function) whose body references only its own parameters, locals, or globals — e.g. the `doBar` helper inside `doFoo` in the rule docs. The parent scope can be a function, block, or IIFE; the check is that no reference inside the function resolves to a binding of the outer scope.

Common situations: Helper functions defined inside React components, event handlers, or route handlers; per-request server code recreating identical closures; teams enabling unicorn presets on an existing codebase.

Related errors


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