{"record":{"id":"4ce7db0efb6e3e78","repo":"oxc-project/oxc","slug":"unnecessary-escape-character-escape-char","errorCode":null,"errorMessage":"Unnecessary escape character {escape_char:?}","messagePattern":"Unnecessary escape character (.+?)","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_useless_escape.rs","lineNumber":21,"sourceCode":"use oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_regular_expression::{\n    ast::{Character, CharacterClass},\n    visit::{RegExpAstKind, Visit},\n};\nuse oxc_semantic::NodeId;\nuse oxc_span::Span;\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn no_useless_escape_diagnostic(escape_char: char, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"Unnecessary escape character {escape_char:?}\")).with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Deserialize)]\npub struct NoUselessEscape(Box<NoUselessEscapeConfig>);\n\nimpl std::ops::Deref for NoUselessEscape {\n    type Target = NoUselessEscapeConfig;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoUselessEscapeConfig {\n    /// An array of characters that are allowed to be escaped unnecessarily in regexes.\n    /// For example, setting this to `[\"#\"]` allows `\\#` in regexes.","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_useless_escape.rs#L3-L39","documentation":"Diagnostic from the `no-useless-escape` rule. A backslash precedes a character that has no special meaning in the current context (string literal, template literal, or regex), so the escape is noise. Oxc formats the character with `{:?}` so whitespace/control characters print safely and labels the exact escape span.","triggerScenarios":"Strings like `\"\\e\"`, `'\\#'`, or `\"\\'\"` inside double quotes; regexes like `/\\-/`, `/\\%/` where the char is not a metacharacter. The rule inspects string/template/regex literal escape sequences and compares against characters that actually require escaping in that context.","commonSituations":"Over-escaped shell commands or grep patterns pasted into JS; regexes written for another flavor (e.g. `\\-` needed inside character classes in some engines but not plain regex); code escaped for JSON or HTML then unescaped once too many.","solutions":["Remove the backslash: `\"\\e\"` -> `\"e\"`, `/a\\-b/` -> `/a-b/`.","Inside regex character classes, keep escapes only for class metacharacters (`]`, `\\\\`, `^`, `-`).","If the literal must contain a real backslash, double it: `\"\\\\d\"` for a literal backslash-d.","Use `oxlint --fix` to strip useless escapes automatically."],"exampleFix":"// before\nconst s = \"hel\\lo\";\nconst re = /\\=/;\n\n// after\nconst s = \"hello\";\nconst re = /=/;","handlingStrategy":"validation","validationCode":"const hasUselessEscape = /\\\\([^nrtbfvxdDsSwWu0-9'`\"\\\\\\/\\[\\](){}^$.+*?|-])/g.test(literalRaw);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Escape only characters that are special in the current context (string vs regex vs class).","For a literal backslash in a string, write `\\\\\\\\`.","Paste regexes through a validator (regex101 JS flavor) to see dead escapes."],"tags":["lint","eslint","oxlint","escape-sequences","string","regex"],"backgroundTag":"no-useless-escape","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"}