oxc-project/oxc · warning · OxcDiagnostic
Unnecessary escape character {escape_char:?}
Error message
Unnecessary escape character {escape_char:?} What it means
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.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_useless_escape.rs:21
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_regular_expression::{
ast::{Character, CharacterClass},
visit::{RegExpAstKind, Visit},
};
use oxc_semantic::NodeId;
use oxc_span::Span;
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
fn no_useless_escape_diagnostic(escape_char: char, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Unnecessary escape character {escape_char:?}")).with_label(span)
}
#[derive(Debug, Default, Clone, Deserialize)]
pub struct NoUselessEscape(Box<NoUselessEscapeConfig>);
impl std::ops::Deref for NoUselessEscape {
type Target = NoUselessEscapeConfig;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoUselessEscapeConfig {
/// An array of characters that are allowed to be escaped unnecessarily in regexes.
/// For example, setting this to `["#"]` allows `\#` in regexes.View on GitHub (pinned to e1e7af627c)
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.
Example fix
// before const s = "hel\lo"; const re = /\=/; // after const s = "hello"; const re = /=/;
Defensive patterns
Strategy: validation
Validate before calling
const hasUselessEscape = /\\([^nrtbfvxdDsSwWu0-9'`"\\\/\[\](){}^$.+*?|-])/g.test(literalRaw); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unexpected implicit coercion to string
- Backreference '{back_reference}' will be ignored. It referen
- Backreference '{back_reference}' will be ignored. It referen
- Backreference '{back_reference}' will be ignored. It referen
- Unexpected string concatenation of literals.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/4ce7db0efb6e3e78.
Report an issue: GitHub.