oxc-project/oxc · warning · OxcDiagnostic
this expression is assigned to itself
Error message
this expression is assigned to itself
What it means
oxlint's port of ESLint `no-self-assign`. It fires when both sides of an assignment are structurally the same target: `a = a`, `obj.a = obj.a` (with `props: true`, the default), and equivalent destructuring/array forms. Self-assignment has no effect (unless a proxy/setter is involved) and almost always indicates a typo or unfinished refactor.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_self_assign.rs:23
AssignmentTargetProperty, Expression, MemberExpression, ObjectProperty, ObjectPropertyKind,
SimpleAssignmentTarget, match_assignment_target, match_simple_assignment_target,
},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_syntax::operator::AssignmentOperator;
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
fn no_self_assign_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("this expression is assigned to itself")
.with_help("Remove the self-assignment or assign to a different variable.")
.with_label(span)
}
#[derive(Debug, Clone, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoSelfAssign {
/// The `props` option when set to `false`, disables the checking of properties.
///
/// With `props` set to `false` the following are examples of correct code:
/// ```javascript
/// obj.a = obj.a;
/// obj.a.b = obj.a.b;
/// obj["a"] = obj["a"];
/// obj[a] = obj[a];
/// ```
props: bool,
}View on GitHub (pinned to e1e7af627c)
Solutions
- Delete the self-assignment statement.
- Fix the intended right-hand side (`obj.a = obj.b;`).
- If you truly need to invoke a setter, call an explicit method or use `void obj.a;` reading the property, and suppress with an `oxlint-ignore no-self-assign` comment.
- Set `"props": false` when property self-assignment must be allowed wholesale.
Example fix
// before obj.a = obj.a; // after obj.a = obj.b;
Defensive patterns
Strategy: validation
Validate before calling
// AST-free heuristic for self-assignment lines
function selfAssignments(src) {
return [...src.matchAll(/^\s*([\w$.]+)\s*=\s*\1\s*;?\s*$/gm)].map(m => m[0]);
} Prevention
- After rename refactors, search for `X = X` patterns in the touched files.
- Treat setters that must run as explicit method calls rather than self-assignment tricks.
- Leave `"props": true` (default) on — property self-assign is the most common typo shape.
When it happens
Trigger: `a = a;`, `this.x = this.x;`, `obj.a = obj.a` with default `props: true`; setting `"props": false` limits the check to plain identifiers. Array patterns like `[a] = [a];` are also covered.
Common situations: Rename refactors that missed one side; copy-paste of `x = y` lines; the rare intentional case of triggering a setter via `el.checked = el.checked`.
Related errors
- Both sides of this comparison are exactly the same
- Setter cannot return a value
- Empty array binding pattern
- Empty object binding pattern
- `debugger` statement is not allowed
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/88a0433832a6040a.
Report an issue: GitHub.