oxc-project/oxc · warning · OxcDiagnostic
Unexpected use of comma operator
Error message
Unexpected use of comma operator
What it means
oxlint's port of ESLint `no-sequences`. It flags the comma operator, which evaluates both operands and returns the last — a construct that hides side effects and is frequently a typo for semicolons or for array literals. With `allowInParentheses: false` (oxlint default), even explicitly parenthesized sequences like `(a, b)` are flagged; setting it true permits sequences wrapped in parentheses.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_sequences.rs:14
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
AstNode, ast_util::outermost_paren_parent, context::LintContext, rule::DefaultRuleConfig,
rule::Rule,
};
fn no_sequences_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected use of comma operator")
.with_help("Do not use the comma operator. If you intended to write a sequence, wrap it in parentheses.")
.with_label(span)
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoSequences {
/// If this option is set to `false`, this rule disallows the comma operator
/// even when the expression sequence is explicitly wrapped in parentheses.
allow_in_parentheses: bool,
}
impl Default for NoSequences {
fn default() -> Self {
Self { allow_in_parentheses: true }
}
}
View on GitHub (pinned to e1e7af627c)
Solutions
- Split into separate statements: `a(); const y = b;`.
- If both results are needed, use an array `const [r1, r2] = [a(), b];` or chaining with `&&`.
- For deliberate short sequences, keep them in a `for` header or set `"allowInParentheses": true`.
Example fix
// before const y = (sideEffect(), value); // after sideEffect(); const y = value;
Defensive patterns
Strategy: validation
Validate before calling
// Find comma-operator sequences outside for-headers
function sequenceOutsideFor(src) {
const noFor = src.replace(/for\s*\([^)]*\)/g, '');
return /\((?:[^()]*,)+[^()]*\)(?!\s*\()/.test(noFor) && /,/.test(noFor.replace(/\[[^\]]*\]/g, ''));
} Prevention
- Default to separate statements; reach for `&&` chaining only when short-circuiting is the point.
- Keep the only comma sequences in `for` headers (`for (let i = 0, j = n; ...)`).
- Run new third-party snippets through oxlint before pasting them into the codebase.
When it happens
Trigger: `x = (1, 2);`, `const y = (a(), b);`, `if ((a, b)) ...`, `return 1, 2;` — the rule inspects SequenceExpression nodes found via `outermost_paren_parent`. Sequence expressions in `for` headers are the conventional tolerated location.
Common situations: Minified/hand-compressed code pasted into a repo; obfuscated snippets; accidental comma where a semicolon or `&&` was intended.
Related errors
- Returned expression contains an assignment.
- Empty array binding pattern
- Empty object binding pattern
- `debugger` statement is not allowed
- Variables should not be deleted
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/86a491e54ed10856.
Report an issue: GitHub.