{"record":{"id":"b1e05e6a61725a5c","repo":"nodejs/node","slug":"u-parse-error","errorCode":"U_PARSE_ERROR","errorMessage":"icupkg: syntax error (more than one '*') in item pattern \"%s\"\n","messagePattern":"icupkg: syntax error \\(more than one '\\*'\\) in item pattern \"(.+?)\"\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"deps/icu-small/source/tools/toolutil/package.cpp","lineNumber":959,"sourceCode":"        return;\n    }\n\n    findPrefix=pattern;\n    findSuffix=nullptr;\n    findSuffixLength=0;\n\n    wild=strchr(pattern, '*');\n    if(wild==nullptr) {\n        // no wildcard\n        findPrefixLength = static_cast<int32_t>(strlen(pattern));\n    } else {\n        // one wildcard\n        findPrefixLength = static_cast<int32_t>(wild - pattern);\n        findSuffix=wild+1;\n        findSuffixLength = static_cast<int32_t>(strlen(findSuffix));\n        if(nullptr!=strchr(findSuffix, '*')) {\n            // two or more wildcards\n            fprintf(stderr, \"icupkg: syntax error (more than one '*') in item pattern \\\"%s\\\"\\n\", pattern);\n            exit(U_PARSE_ERROR);\n        }\n    }\n\n    if(findPrefixLength==0) {\n        findNextIndex=0;\n    } else {\n        findNextIndex=findItem(findPrefix, findPrefixLength);\n    }\n}\n\nint32_t\nPackage::findNextItem() {\n    const char *name, *middle, *treeSep;\n    int32_t idx, nameLength, middleLength;\n\n    if(findNextIndex<0) {\n        return -1;","sourceCodeStart":941,"sourceCodeEnd":977,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/icu-small/source/tools/toolutil/package.cpp#L941-L977","documentation":"icupkg accepts item patterns with at most one '*' wildcard (a prefix and optional suffix). If a pattern contains two or more asterisks, parsing is ambiguous and the tool exits with U_PARSE_ERROR. This affects findNext/match operations used by -l/-x/-r item selectors.","triggerScenarios":"In the pattern parser, after locating the first '*' and computing findSuffix, 'strchr(findSuffix, '*')' returns non-null (a second wildcard). Fires for patterns like 'foo*bar*baz' or '**'.","commonSituations":"Shell-glob habits leaking into icupkg item patterns; a typo doubling the asterisk; scripting that concatenates wildcard fragments producing '**'.","solutions":["Reduce the pattern to a single wildcard, e.g. 'foo*bar' instead of 'foo*bar*'.","Quote the pattern to prevent shell glob expansion from injecting extra '*' characters.","Run two separate icupkg invocations with single-wildcard patterns if you need broader matching."],"exampleFix":"# before\nicupkg in.dat -x 'res_*_*.res'\n\n# after - single wildcard, quoted\nicupkg in.dat -x 'res_*'","handlingStrategy":"type-guard","validationCode":"# Reject item patterns with more than one '*' before passing to icupkg.\nvalid_pattern() {\n  local p=\"$1\"\n  # remove the first '*', ensure none remain\n  [ \"${p/\\*}\" = \"$p\" ] && return 0   # zero wildcards: ok\n  rest=\"${p#*\\*}\"\n  case \"$rest\" in *'*'*) return 1 ;; *) return 0 ;; esac\n}\nvalid_pattern \"$PAT\" || { echo \"pattern '$PAT' has >1 wildcard\" >&2; exit 1; }\nicupkg in.dat -x \"$PAT\"","typeGuard":"// TypeScript/JS type guard for an icupkg item pattern (at most one '*').\nfunction isIcupkgItemPattern(p: string): boolean {\n  const first = p.indexOf('*');\n  if (first === -1) return true;            // no wildcard\n  return p.indexOf('*', first + 1) === -1;  // no second wildcard\n}","tryCatchPattern":null,"preventionTips":["Quote icupkg patterns to stop the shell from expanding globs.","Use at most one '*' per pattern; run multiple icupkg calls for broader matching.","Add a pattern validator in build scripts that compose wildcard fragments."],"tags":["icu","icupkg","input-validation","pattern-matching","cli-tool","parse-error"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}