nodejs/node · error
U_ILLEGAL_ESCAPE_SEQUENCE
U_ILLEGAL_ESCAPE_SEQUENCE
Error message
Bad escape: [%c%s]...
What it means
Emitted from the escape-parsing helper invoked while reading resource-bundle / rules text. u_unescapeAt returns the sentinel 0xFFFFFFFF when it cannot interpret the backslash escape beginning with character c1. With showWarning the raw offending context is printed; the helper then sets *error = U_ILLEGAL_ESCAPE_SEQUENCE and returns the lead character c1 without consuming the buffer.
Source
Thrown at deps/icu-small/source/tools/toolutil/ucbuf.cpp:429
}
/* Process the escape */
offset = 0;
c32 = u_unescapeAt(_charAt, &offset, length, (void*)buf);
/* check if u_unescapeAt unescaped and converted
* to c32 or not
*/
if(c32==(UChar32)0xFFFFFFFF){
if(buf->showWarning) {
char context[CONTEXT_LEN+1];
int32_t len = CONTEXT_LEN;
if(length < len) {
len = length;
}
context[len]= 0 ; /* null terminate the buffer */
u_UCharsToChars( buf->currentPos, context, len);
fprintf(stderr,"Bad escape: [%c%s]...\n", (int)c1, context);
}
*error= U_ILLEGAL_ESCAPE_SEQUENCE;
return c1;
}else if(c32!=c2 || (c32==0x0075 && c2==0x0075 && c1==0x005C) /* for \u0075 c2=0x0075 and c32==0x0075*/){
/* Update the current buffer position */
buf->currentPos += offset;
}else{
/* unescaping failed so we just return
* c1 and not consume the buffer
* this is useful for rules with escapes
* in resource bundles
* eg: \' \\ \"
*/
return c1;
}
return c32;
}View on GitHub (pinned to 1b2de5e052)
Solutions
- Open the file at the reported offset and fix the escape: complete \uXXXX / \UXXXXXXXX with the correct number of hex digits.
- Use a literal backslash as \\ and quote other specials with the supported resource-bundle escapes (\' \\ \").
- Run the file through a JSON/ICU unescape linter (e.g. icu u_unescape round-trip) to flag every invalid escape before feeding it to the tool.
- If the backslash is intended literally in rule data, double-escape it (\\) so u_unescapeAt sees a valid sequence.
Example fix
// before (.txt resource bundle fragment):
// "key" { "price \u12 each \q mark" }
// after:
// "key" { "price \u0012 each \\q mark" } Defensive patterns
Strategy: validation
Validate before calling
// Scan the text for backslash escapes u_unescapeAt would reject.
#include <unicode/unistr.h>
// Returns offset of the first bad escape, or -1.
int32_t first_bad_escape(const UChar* s, int32_t len) {
for (int32_t i = 0; i < len; ++i) {
if (s[i] == 0x5C /* \ */ && i + 1 < len) {
UChar32 c0 = s[i + 1];
// quick reject of escapes u_unescapeAt does not support
const UChar ok[] = u"'\"\\abfnrtuUuxUN?"; // supported lead chars
bool known = false;
for (UChar o : ok) if (o == c0) { known = true; break; }
if (!known) return i;
}
}
return -1;
} Try / catch
UErrorCode status = U_ZERO_ERROR;
// ... read UCHARBUF, call the escape-consuming API ...
if (status == U_ILLEGAL_ESCAPE_SEQUENCE) {
// The 'Bad escape' line already named the lead char + context.
// Report file/line and abort the resource build; do not mask it.
return EXIT_FAILURE;
} Prevention
- Lint resource .txt files in CI with a JSON/ICU unescape checker before invoking genrb.
- Always double backslashes (\\) for literal backslashes and use only \' \\ \" in rule-bundle literals.
- Reject \u/\U/\x with anything other than the required count of hex digits.
- Generate locale data programmatically rather than hand-typing escapes.
When it happens
Trigger: A .txt resource bundle or rules file contains a malformed backslash escape: an unsupported escape like \q or \k; \x with non-hex digits (\xZZ); a truncated \u / \U with fewer than 4/8 hex digits (\u12, \U001); or any backslash sequence not in the resource-bundle escape set (\' \\ \").
Common situations: Hand-typed locale .txt files with typos in \uXXXX escapes; copy-paste that doubled or stripped backslashes; tooling that emitted non-hex digits after \u/\U/\x; a literal backslash in content that was not doubled.
Related errors
- couldn't parse the file %s. Error:%s
- %s:%d: %s\n
- Unable to open directory: %s\n
- Unable to get stats from file: %s or %s\n
- U_ILLEGAL_ARGUMENT_ERROR
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/631ee46f2f54fc37.
Report an issue: GitHub.