oxc-project/oxc · warning · OxcDiagnostic

{name} has a complexity of {complexity}. Maximum allowed is

Error message

{name} has a complexity of {complexity}. Maximum allowed is {max}.

What it means

Oxlint's port of the ESLint rule complexity. It counts the independent branch points of a function (if/else-if, loops, case clauses, catch, short-circuit operators, ternaries) and reports the function when the total exceeds the configured maximum. The message interpolates the function description from get_function_name_with_kind, the measured complexity, and the limit. The default threshold is 20 (THRESHOLD_DEFAULT at crates/oxc_linter/src/rules/eslint/complexity.rs:27) and the config field `max` also accepts the ESLint-style alias `maximum`.

Source

Thrown at crates/oxc_linter/src/rules/eslint/complexity.rs:21

use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::ScopeFlags;
use oxc_span::{GetSpan, Span};
use oxc_syntax::operator::AssignmentOperator;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::ops::Deref;

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

fn complexity_diagnostic(span: Span, name: &str, complexity: u32, max: u32) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "{name} has a complexity of {complexity}. Maximum allowed is {max}."
    ))
    .with_label(span)
}

const THRESHOLD_DEFAULT: u32 = 20;

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct ComplexityConfig {
    /// Maximum amount of cyclomatic complexity
    #[serde(alias = "maximum")]
    max: u32,
    /// The cyclomatic complexity variant to use
    variant: Variant,
}

impl Default for ComplexityConfig {

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Refactor the function: split responsibilities, use early returns, or replace long branch chains with a lookup table or map dispatch.
  2. Raise the limit if it is unrealistic for the codebase: { "complexity": ["warn", { "max": 30 }] }.
  3. Suppress the single occurrence with `// oxlint-disable-line complexity` while scheduling the refactor.
  4. Extract nested conditionals into named predicate functions so each unit stays under the limit.

Example fix

// before (complexity 22)
function route(req) {
  if (req.t === 'a') { return fa(req); }
  else if (req.t === 'b') { return fb(req); }
  /* 20 more branches */
}

// after
const routes = { a: fa, b: fb };
function route(req) {
  return (routes[req.t] ?? unknown)(req);
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json — pick a threshold the codebase actually passes
{
  "rules": {
    "complexity": ["warn", { "max": 30 }]
  }
}

Prevention

When it happens

Trigger: Linting any function whose counted decision points exceed `max` (default 20), e.g. a function with 15 if/else-if branches plus 6 `&&`/`||` operators reports complexity 22 against max 20. Lowering `max` in .oxlintrc.json immediately reports more functions.

Common situations: Enabling complexity on a brownfield codebase with long dispatch or validation functions; migrating an ESLint config that used the `maximum` key; CI failures after a team tightens the limit without refactoring first.

Related errors


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