{"record":{"id":"39a5fd5d1929c10a","repo":"oxc-project/oxc","slug":"backreference-back-reference-will-be-ignored-39a5fd","errorCode":null,"errorMessage":"Backreference '{back_reference}' will be ignored. It references group '{group}' which appears later in the pattern.","messagePattern":"Backreference '(.+?)' will be ignored\\. It references group '(.+?)' which appears later in the pattern\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_useless_backreference.rs","lineNumber":26,"sourceCode":"use oxc_span::Span;\n\nuse crate::{AstNode, context::LintContext, rule::Rule, utils::run_on_regex_node};\n\nfn no_useless_backreference_diagnostic(\n    span: Span,\n    problem: &Problem,\n    back_reference: &str,\n    group: &str,\n) -> OxcDiagnostic {\n    let diagnostic = match problem {\n        Problem::Nested => OxcDiagnostic::warn(format!(\n            \"Backreference '{back_reference}' will be ignored. It references group '{group}' from within that group.\"\n        )),\n        Problem::Disjunctive => OxcDiagnostic::warn(format!(\n            \"Backreference '{back_reference}' will be ignored. It references group '{group}' which is in another alternative.\"\n        )),\n        Problem::Forward => OxcDiagnostic::warn(format!(\n            \"Backreference '{back_reference}' will be ignored. It references group '{group}' which appears later in the pattern.\"\n        )),\n        Problem::Backward => OxcDiagnostic::warn(format!(\n            \"Backreference '{back_reference}' will be ignored. It references group '{group}' which appears before in the same lookbehind.\"\n        )),\n        Problem::IntoNegativeLookaround => OxcDiagnostic::warn(format!(\n            \"Backreference '{back_reference}' will be ignored. It references group '{group}' which is in a negative lookaround.\"\n        )),\n    };\n    diagnostic\n        .with_help(\"Consider revising the pattern to remove or relocate the backreference so it points to a group that can be matched at the time of evaluation.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoUselessBackreference;\n\ndeclare_oxc_lint!(\n    /// ### What it does","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_useless_backreference.rs#L8-L44","documentation":"This is an oxlint diagnostic from the ESLint-compatible rule `no-useless-backreference` (variant `Forward`). A regex backreference such as \\1 refers to a capture group that is defined later in the pattern, so at evaluation time the group has not yet captured anything and the backreference always matches the empty string. Oxc's regex analyzer flags it because the reference is provably dead code inside the pattern.","triggerScenarios":"Writing a regex literal or `new RegExp` where a backreference number points forward, e.g. `/\\1(a)/` or `/(?:a)|(?:\\2(b))/`-style patterns where the group appears after the reference. Any visitor run over LiteralRegex/RegExp calls in oxc_linter emits this when the group index resolves to a span later than the backreference.","commonSituations":"Copy-pasted patterns edited so a group moved after its reference; renumbering groups after inserting a new capture group early in the pattern; hand-built dynamic patterns where the author lost track of group order.","solutions":["Move the capture group before the backreference so it is defined earlier, e.g. `/\\1(a)/` -> `/(a)\\1/`.","If the intent was a literal character, replace the backreference with the literal text or a group that exists before it.","If the reference is intentional documentation, rewrite the pattern (e.g. duplicate the subpattern instead of referencing it).","Disable the rule for the line with an oxlint disable comment (`// oxlint-disable-next-line no-useless-backreference`) only if you are certain the engine you target gives it meaning."],"exampleFix":"// before\nconst re = /\\1(a)/;\n\n// after\nconst re = /(a)\\1/;","handlingStrategy":"validation","validationCode":"// Before committing a regex, verify every backreference points to an earlier group\nfunction hasForwardBackreference(source) {\n  const groups = [...source.matchAll(/\\((\\?<?[=!:]?|\\?<[^>]+>)?/g)];\n  const refs = [...source.matchAll(/\\\\(\\d+)/g)];\n  return refs.some(([, n]) => Number(n) > /* approximate check */ 0 && source.indexOf(refs[0][0]) < 0);\n}\n// Simplest reliable check: group index must already have an opening '(' before the backreference\nfunction check(re) {\n  let open = 0;\n  for (let i = 0; i < re.source.length; i++) {\n    if (re.source[i] === '(') open++;\n    const m = /^\\\\(\\d+)/.exec(re.source.slice(i));\n    if (m && Number(m[0].slice(1)) > open) return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write capture groups before any backreference that uses them.","After inserting/removing groups, renumber references or use named groups `(?<id>...)` + `\\\\k<id>`.","Keep oxlint in CI so no-useless-backreference catches dead references before merge."],"tags":["lint","eslint","oxlint","regex","static-analysis"],"backgroundTag":"regex-forward-backreference","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"}