nodejs/node · warning
%s:%d: %s\n
Error message
%s:%d: %s\n
What it means
In isFileModTimeLater (filetools.cpp), while recursing through a directory, building the newpath via icu::CharString::append set the local UErrorCode to a failure (typically U_BUFFER_OVERFLOW_ERROR when the concatenated path is too long, or a memory error). The code prints __FILE__, __LINE__, and u_errorName(status), then returns false — treating the comparison as 'not latest', forcing a rebuild of the target.
Source
Thrown at deps/icu-small/source/tools/toolutil/filetools.cpp:66
if (filePath == nullptr || checkAgainst == nullptr) {
return false;
}
if (isDir == true) {
#if U_HAVE_DIRENT_H
DIR *pDir = nullptr;
if ((pDir= opendir(checkAgainst)) != nullptr) {
DIR *subDirp = nullptr;
DIRENT *dirEntry = nullptr;
while ((dirEntry = readdir(pDir)) != nullptr) {
if (uprv_strcmp(dirEntry->d_name, SKIP1) != 0 && uprv_strcmp(dirEntry->d_name, SKIP2) != 0) {
UErrorCode status = U_ZERO_ERROR;
icu::CharString newpath(checkAgainst, -1, status);
newpath.append(U_FILE_SEP_STRING, -1, status);
newpath.append(dirEntry->d_name, -1, status);
if (U_FAILURE(status)) {
fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status));
return false;
}
if ((subDirp = opendir(newpath.data())) != nullptr) {
/* If this new path is a directory, make a recursive call with the newpath. */
closedir(subDirp);
isLatest = isFileModTimeLater(filePath, newpath.data(), isDir);
if (!isLatest) {
break;
}
} else {
int32_t latest = whichFileModTimeIsLater(filePath, newpath.data());
if (latest < 0 || latest == 2) {
isLatest = false;
break;
}
}
View on GitHub (pinned to 1b2de5e052)
Solutions
- Shorten the directory tree depth/names so concatenated paths fit.
- Move the build closer to the filesystem root to cut absolute path length.
- Increase available memory if the failure was allocation-related (inspect u_errorName output).
- Clean and rebuild to remove stale references to long paths.
Example fix
// before: deep path triggers U_BUFFER_OVERFLOW_ERROR in CharString::append /home/user/.../very/deep/icu/data/... // after: shallower root /icu/data/...
Defensive patterns
Strategy: try-catch
Validate before calling
// Mirror the toolutil check: bail if concatenating the entry overflows a CharString-sized buffer.
#include <string.h>
#include <limits.h>
bool pathConcatFits(const char *dir, const char *name, size_t cap) {
size_t need = strlen(dir) + 1 + strlen(name) + 1;
return need < cap && need < PATH_MAX;
} Try / catch
// ICU C++ pattern: check the UErrorCode after each CharString op, as toolutil does.
icu::CharString p;
UErrorCode status = U_ZERO_ERROR;
p.append(dir, -1, status);
p.append(U_FILE_SEP_STRING, -1, status);
p.append(name, -1, status);
if (U_FAILURE(status)) { /* log u_errorName(status); skip this entry */ } Prevention
- Keep directory trees shallow so concatenated paths fit.
- Always check U_FAILURE(status) after CharString::append.
- Move the build root closer to / to shorten paths.
- Log u_errorName(status) to distinguish overflow from allocation failure.
When it happens
Trigger: The directory entry name appended to checkAgainst overflows the CharString's internal buffer (very long path), or an allocation inside append fails. U_FAILURE(status) becomes true, newpath is invalid, and recursion aborts.
Common situations: A build tree with extremely long paths exceeding ICU toolutil's path limits; deeply nested resource directories; a corrupt dirent returning an overlong d_name.
Related errors
- Unable to open directory: %s\n
- Unable to get stats from file: %s or %s\n
- U_ILLEGAL_ARGUMENT_ERROR
- 0
- ## ERR: Path too long [%d chars]: %s\n
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/88ff4f68fddafb7c.
Report an issue: GitHub.