{"record":{"id":"af2a53226d888110","repo":"oxc-project/oxc","slug":"math-min-and-math-max-combination-leads-to-constan","errorCode":null,"errorMessage":"Math.min and Math.max combination leads to constant result","messagePattern":"Math\\.min and Math\\.max combination leads to constant result","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/oxc/bad_min_max_func.rs","lineNumber":12,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{Argument, CallExpression, Expression},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn bad_min_max_func_diagnostic(constant_result: f64, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Math.min and Math.max combination leads to constant result\")\n        .with_help(format!(\n            \"This evaluates to {constant_result:?} because of the incorrect `Math.min`/`Math.max` combination\"\n        ))\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct BadMinMaxFunc;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Checks whether the clamp function `Math.min(Math.max(x, y), z)` always evaluates to a\n    /// constant result because the arguments are in the wrong order.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// The `Math.min(Math.max(x, y), z)` function is used to clamp a value between two other values.","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/oxc/bad_min_max_func.rs#L1-L30","documentation":"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.","triggerScenarios":"`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))`.","commonSituations":"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.","solutions":["Reorder so the lower bound goes in `Math.max` and the upper bound in `Math.min`: `Math.min(100, Math.max(0, x))`","Double-check which of the two constants is smaller before nesting the calls","Extract a `clamp(x, lo, hi)` helper so the argument order is encoded once and unit-tested","Keep `oxc/bad-min-max-func` (correctness) enabled in CI"],"exampleFix":"// before\nconst clamped = Math.min(Math.max(100, x), 0); // always 0\n\n// after\nconst clamped = Math.min(100, Math.max(0, x));","handlingStrategy":"validation","validationCode":"// .oxlintrc.json — fail CI on this bug class\n{\n  \"rules\": { \"oxc/bad-min-max-func\": \"error\" }\n}\n// CLI: npx oxlint src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Memorize the canonical clamp shape: Math.min(HI, Math.max(LO, x))","Unit-test clamp helpers with inputs below LO, inside, and above HI — a collapsed constant fails all three","Centralize clamping in one helper so the argument order is verified once"],"tags":["oxlint","oxc","math","clamp","logic-bug","javascript"],"backgroundTag":"math-clamp-bounds-swapped","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}