nodejs/node · error

toolutil/getCPTrieSize error: ucptrie_toBinary() failed: %s

Error message

toolutil/getCPTrieSize error: ucptrie_toBinary() failed: %s (length %ld)

What it means

Thrown by getCPTrieSize() when ucptrie_toBinary() fails during serialization of a built immutable trie to a binary buffer. The function uses a fixed 100000-byte stack buffer; U_BUFFER_OVERFLOW_ERROR is explicitly filtered out (since the needed size is still returned in that case), so this error fires only on genuine serialization failures.

Source

Thrown at deps/icu-small/source/tools/toolutil/toolutil.cpp:144

        }
        start = rangeEnd + 1;
    }
}

int32_t getCPTrieSize(UMutableCPTrie *mt, UCPTrieType type, UCPTrieValueWidth valueWidth) {
    UErrorCode errorCode = U_ZERO_ERROR;
    UCPTrie *cpTrie = umutablecptrie_buildImmutable(mt, type, valueWidth, &errorCode);
    if (U_FAILURE(errorCode)) {
        fprintf(stderr,
                "toolutil/getCPTrieSize error: umutablecptrie_buildImmutable() failed: %s\n",
                u_errorName(errorCode));
        return -1;
    }
    uint8_t block[100000];
    int32_t size = ucptrie_toBinary(cpTrie, block, sizeof(block), &errorCode);
    ucptrie_close(cpTrie);
    if (U_FAILURE(errorCode) && errorCode != U_BUFFER_OVERFLOW_ERROR) {
        fprintf(stderr,
                "toolutil/getCPTrieSize error: ucptrie_toBinary() failed: %s (length %ld)\n",
                u_errorName(errorCode), static_cast<long>(size));
        return -1;
    }
    U_ASSERT((size & 3) == 0);  // multiple of 4 bytes
    return size;
}

}  // toolutil

U_NAMESPACE_END

static int32_t currentYear = -1;

U_CAPI int32_t U_EXPORT2 getCurrentYear() {
    if(currentYear == -1) {
        time_t now = time(nullptr);
        tm *fields = gmtime(&now);

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Examine the specific ICU error name and reported length in the message.
  2. Rebuild the trie from scratch to rule out memory corruption.
  3. Check for ICU version mismatches between the trie-building and serialization code paths.
  4. Report as a potential ICU bug if the trie builds successfully but fails to serialize.
  5. Verify no memory corruption by running under AddressSanitizer or Valgrind.
Defensive patterns

Strategy: validation

Validate before calling

// Verify trie is valid after build before calling getCPTrieSize
#include <unicode/ucptrie.h>

bool trieIsBuildable(UMutableCPTrie* mt, UCPTrieType type, UCPTrieValueWidth width) {
    UErrorCode err = U_ZERO_ERROR;
    UCPTrie* test = umutablecptrie_buildImmutable(mt, type, width, &err);
    if (U_FAILURE(err)) return false;
    // Test serialization with a small buffer to check for non-overflow errors
    uint8_t smallBuf[64];
    int32_t sz = ucptrie_toBinary(test, smallBuf, sizeof(smallBuf), &err);
    ucptrie_close(test);
    // U_BUFFER_OVERFLOW_ERROR is expected and OK
    return (err == U_ZERO_ERROR || err == U_BUFFER_OVERFLOW_ERROR);
}

Try / catch

int32_t size = getCPTrieSize(mt, type, valueWidth);
if (size < 0) {
    // Either buildImmutable or toBinary failed
    fprintf(stderr, "getCPTrieSize returned %d; trie may be corrupt\n", size);
    umutablecptrie_close(mt);
    return U_INVALID_FORMAT_ERROR;
}

Prevention

When it happens

Trigger: ucptrie_toBinary() fails with an error other than U_BUFFER_OVERFLOW_ERROR after umutablecptrie_buildImmutable succeeded. This indicates the immutable trie is internally inconsistent or corrupted in a way that prevents serialization, despite building successfully.

Common situations: Very rare; could indicate a bug in the trie building logic, memory corruption affecting the trie structure, or an ICU version where buildImmutable and toBinary have inconsistent assumptions about trie validity.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/d2ec943c6066d958. Report an issue: GitHub.