angular/angular · error · Error
Error in attribute selector "${attr}". Unescaped "$" is not
Error message
Error in attribute selector "${attr}". Unescaped "$" is not supported. Please escape with "\$". What it means
unescapeAttribute runs over attribute names parsed from a selector and rejects a '$' that was not preceded by a backslash. Angular uses '$' internally when encoding special attribute prefixes (attr./style./class.), so a raw '$' in an attribute selector is ambiguous; source selectors must write '\$' which this function unescapes.
Source
Thrown at packages/compiler/src/directive_matching.ts:143
*
* This is needed because `$` can have a special meaning in CSS selectors,
* but we might want to match an attribute that contains `$`.
* [MDN web link for more
* info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
* @param attr the attribute to unescape.
* @returns the unescaped string.
*/
unescapeAttribute(attr: string): string {
let result = '';
let escaping = false;
for (let i = 0; i < attr.length; i++) {
const char = attr.charAt(i);
if (char === '\\') {
escaping = true;
continue;
}
if (char === '$' && !escaping) {
throw new Error(
`Error in attribute selector "${attr}". ` +
`Unescaped "$" is not supported. Please escape with "\\$".`,
);
}
escaping = false;
result += char;
}
return result;
}
/**
* Escape `$` sequences from the CSS attribute selector.
*
* This is needed because `$` can have a special meaning in CSS selectors,
* with this method we are escaping `$` with `\$'.
* [MDN web link for more
* info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
* @param attr the attribute to escape.View on GitHub (pinned to 51cb07e980)
Solutions
- Escape the dollar in the selector: '[data-test\$]' (backslash-dollar inside the string literal).
- Or rename the attribute to avoid '$' entirely — cleaner for attribute binding and template readability.
Example fix
// before
@Directive({selector: '[data-flag$]'})
// after
@Directive({selector: '[data-flag\$]'}) // '\$' unescapes to a literal '$' attribute Defensive patterns
Strategy: validation
Validate before calling
const hasUnescapedDollar = (selector: string): boolean =>
/\[[^\]]*(?<!\\)\$/.test(selector); // '$' inside an attribute selector without a preceding '\'
function assertValidAttributeSelector(selector: string): void {
if (hasUnescapedDollar(selector)) {
throw new Error(`Attribute selector "${selector}" contains an unescaped '$'; write '\\$'`);
}
} Prevention
- Avoid '$' in attribute names consumed by Angular (skip observable-style suffixes like count$).
- When '$' is required, always escape it in the selector string ('\\$') and cover it with a selector unit test.
When it happens
Trigger: An attribute selector whose attribute name contains an unescaped dollar: '[data-test$]', '[foo$bar="v"]' in a @Directive/@Component selector or ng-content select.
Common situations: Naming conventions that include '$' (observable-style names like count$, data$) leaking into attribute selector names; test attributes generated by tooling.
Related errors
- Nesting :not in a selector is not allowed
- Multiple selectors in :not are not supported
- DIRECTIVE_MISSING_SELECTOR
- found start event for frame capture, but frame capture was n
- missing start event for frame capture
AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22).
Data as JSON: /api/errors/27a0d0c2b16f8b00.
Report an issue: GitHub.