{"record":{"id":"631ee46f2f54fc37","repo":"nodejs/node","slug":"u-illegal-escape-sequence","errorCode":"U_ILLEGAL_ESCAPE_SEQUENCE","errorMessage":"Bad escape: [%c%s]...\n","messagePattern":"Bad escape: \\[%c(.+?)\\]\\.\\.\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"deps/icu-small/source/tools/toolutil/ucbuf.cpp","lineNumber":429,"sourceCode":"    }\n\n    /* Process the escape */\n    offset = 0;\n    c32 = u_unescapeAt(_charAt, &offset, length, (void*)buf);\n\n    /* check if u_unescapeAt unescaped and converted\n     * to c32 or not\n     */\n    if(c32==(UChar32)0xFFFFFFFF){\n        if(buf->showWarning) {\n            char context[CONTEXT_LEN+1];\n            int32_t len = CONTEXT_LEN;\n            if(length < len) {\n                len = length; \n            }\n            context[len]= 0 ; /* null terminate the buffer */\n            u_UCharsToChars( buf->currentPos, context, len);\n            fprintf(stderr,\"Bad escape: [%c%s]...\\n\", (int)c1, context);\n        }\n        *error= U_ILLEGAL_ESCAPE_SEQUENCE;\n        return c1;\n    }else if(c32!=c2 || (c32==0x0075 && c2==0x0075 && c1==0x005C) /* for \\u0075 c2=0x0075 and c32==0x0075*/){\n        /* Update the current buffer position */\n        buf->currentPos += offset;\n    }else{\n        /* unescaping failed so we just return\n         * c1 and not consume the buffer\n         * this is useful for rules with escapes\n         * in resource bundles\n         * eg: \\' \\\\ \\\"\n         */\n        return c1;\n    }\n\n    return c32;\n}","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/icu-small/source/tools/toolutil/ucbuf.cpp#L411-L447","documentation":"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.","triggerScenarios":"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 (\\' \\\\ \\\").","commonSituations":"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.","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."],"exampleFix":"// before (.txt resource bundle fragment):\n//   \"key\" { \"price \\u12 each \\q mark\" }\n// after:\n//   \"key\" { \"price \\u0012 each \\\\q mark\" }","handlingStrategy":"validation","validationCode":"// Scan the text for backslash escapes u_unescapeAt would reject.\n#include <unicode/unistr.h>\n// Returns offset of the first bad escape, or -1.\nint32_t first_bad_escape(const UChar* s, int32_t len) {\n    for (int32_t i = 0; i < len; ++i) {\n        if (s[i] == 0x5C /* \\ */ && i + 1 < len) {\n            UChar32 c0 = s[i + 1];\n            // quick reject of escapes u_unescapeAt does not support\n            const UChar ok[] = u\"'\\\"\\\\abfnrtuUuxUN?\"; // supported lead chars\n            bool known = false;\n            for (UChar o : ok) if (o == c0) { known = true; break; }\n            if (!known) return i;\n        }\n    }\n    return -1;\n}","typeGuard":null,"tryCatchPattern":"UErrorCode status = U_ZERO_ERROR;\n// ... read UCHARBUF, call the escape-consuming API ...\nif (status == U_ILLEGAL_ESCAPE_SEQUENCE) {\n    // The 'Bad escape' line already named the lead char + context.\n    // Report file/line and abort the resource build; do not mask it.\n    return EXIT_FAILURE;\n}","preventionTips":["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."],"tags":["icu","escape-sequence","resource-bundle","toolutil","unescape"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}