{"record":{"id":"88a0433832a6040a","repo":"oxc-project/oxc","slug":"this-expression-is-assigned-to-itself","errorCode":null,"errorMessage":"this expression is assigned to itself","messagePattern":"this expression is assigned to itself","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_self_assign.rs","lineNumber":23,"sourceCode":"        AssignmentTargetProperty, Expression, MemberExpression, ObjectProperty, ObjectPropertyKind,\n        SimpleAssignmentTarget, match_assignment_target, match_simple_assignment_target,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse oxc_syntax::operator::AssignmentOperator;\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn no_self_assign_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"this expression is assigned to itself\")\n        .with_help(\"Remove the self-assignment or assign to a different variable.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Clone, Deserialize, JsonSchema)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoSelfAssign {\n    /// The `props` option when set to `false`, disables the checking of properties.\n    ///\n    /// With `props` set to `false` the following are examples of correct code:\n    /// ```javascript\n    /// obj.a = obj.a;\n    /// obj.a.b = obj.a.b;\n    /// obj[\"a\"] = obj[\"a\"];\n    /// obj[a] = obj[a];\n    /// ```\n    props: bool,\n}","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_self_assign.rs#L5-L41","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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`.","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."],"exampleFix":"// before\nobj.a = obj.a;\n\n// after\nobj.a = obj.b;","handlingStrategy":"validation","validationCode":"// AST-free heuristic for self-assignment lines\nfunction selfAssignments(src) {\n  return [...src.matchAll(/^\\s*([\\w$.]+)\\s*=\\s*\\1\\s*;?\\s*$/gm)].map(m => m[0]);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["lint","eslint","no-self-assign","assignments","possible-bug"],"backgroundTag":"self-assignment","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"}