oxc-project/oxc · error · OxcDiagnostic

Math.min and Math.max combination leads to constant result

Error message

Math.min and Math.max combination leads to constant result

What it means

Oxlint rule `oxc/bad-min-max-func` detects a clamp expression `Math.min(Math.max(x, a), b)` (or the mirrored `Math.max(a, Math.min(0, x))`) where the constant bounds are ordered so the whole expression collapses to a constant. The implementation folds the numeric-literal arguments of each `Math.min`/`Math.max` call and reports the constant result (e.g. `Math.min(Math.max(100, x), 0)` always evaluates to 0). It is a correctness bug: the clamp silently returns a fixed number instead of clamping.

Source

Thrown at crates/oxc_linter/src/rules/oxc/bad_min_max_func.rs:12

use oxc_ast::{
    AstKind,
    ast::{Argument, CallExpression, Expression},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

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

fn bad_min_max_func_diagnostic(constant_result: f64, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Math.min and Math.max combination leads to constant result")
        .with_help(format!(
            "This evaluates to {constant_result:?} because of the incorrect `Math.min`/`Math.max` combination"
        ))
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Checks whether the clamp function `Math.min(Math.max(x, y), z)` always evaluates to a
    /// constant result because the arguments are in the wrong order.
    ///
    /// ### Why is this bad?
    ///
    /// The `Math.min(Math.max(x, y), z)` function is used to clamp a value between two other values.

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Reorder so the lower bound goes in `Math.max` and the upper bound in `Math.min`: `Math.min(100, Math.max(0, x))`
  2. Double-check which of the two constants is smaller before nesting the calls
  3. Extract a `clamp(x, lo, hi)` helper so the argument order is encoded once and unit-tested
  4. Keep `oxc/bad-min-max-func` (correctness) enabled in CI

Example fix

// before
const clamped = Math.min(Math.max(100, x), 0); // always 0

// after
const clamped = Math.min(100, Math.max(0, x));
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json — fail CI on this bug class
{
  "rules": { "oxc/bad-min-max-func": "error" }
}
// CLI: npx oxlint src/

Prevention

When it happens

Trigger: `Math.min(Math.max(100, x), 0)` -> always 0; `Math.max(1000, Math.min(0, z))` -> always 1000; bounds spread across extra numeric args like `Math.min(Math.max(1000, x), 100, 3)` -> always 3; also computed access such as `Math["min"](0, Math.max(100, x))`.

Common situations: Writing clamp/normalize helpers (RGB 0-255, percent 0-100) and swapping which bound goes to min vs max; copy-pasting a clamp snippet and editing the bounds; refactoring `Math.max(0, Math.min(100, x))` into the wrong nesting order.

Related errors


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