can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: file name is not valid UTF-8
Error message
Invalid CAB archive: file name is not valid UTF-8
What it means
decodeName decodes a CFFILE entry's name using either a fatal UTF-8 decoder or a legacy decoder; if decoding is not lossless it throws this error rather than silently producing mojibake. Despite the fixed message mentioning UTF-8, this fires when the name bytes are invalid UTF-8 (utf8=true) or invalid in the legacy encoding (utf8=false). The library refuses archives whose entry names cannot be decoded cleanly.
Source
Thrown at packages/utils/src/ar/cab.ts:83
offset += 4;
}
const remaining = bytes.byteLength - offset;
let remainder = 0;
if (remaining === 3) {
remainder = (bytes[offset]! << 16) | (bytes[offset + 1]! << 8) | bytes[offset + 2]!;
} else if (remaining === 2) {
remainder = (bytes[offset]! << 8) | bytes[offset + 1]!;
} else if (remaining === 1) {
remainder = bytes[offset]!;
}
return (checksum ^ remainder) >>> 0;
}
function decodeName(bytes: Uint8Array, utf8: boolean): string {
try {
return utf8 ? UTF8_FATAL_DECODER.decode(bytes) : LEGACY_NAME_DECODER.decode(bytes);
} catch {
throw new ArchiveError("Invalid CAB archive: file name is not valid UTF-8");
}
}
function dosTimestamp(date: number, time: number): number | undefined {
if (date === 0 && time === 0) return undefined;
const year = 1980 + (date >>> 9);
const month = (date >>> 5) & 0x0f;
const day = date & 0x1f;
const hour = time >>> 11;
const minute = (time >>> 5) & 0x3f;
const second = (time & 0x1f) * 2;
if (month < 1 || month > 12 || day < 1 || day > 31 || hour > 23 || minute > 59 || second > 59) {
throw new ArchiveError("Invalid CAB archive: file has an invalid DOS timestamp");
}
return new Date(year, month - 1, day, hour, minute, second).getTime();
}
function modeFromAttributes(attributes: number, directory: boolean): number {View on GitHub (pinned to 9690622007)
Solutions
- Re-create the CAB with UTF-8 file names (e.g. build on modern Windows or with libmspack-compatible tooling using ASCII/UTF-8 names).
- If you control the source, rename entries to ASCII to sidestep codepage ambiguity.
- Inspect the raw name bytes with a hex dump to identify the actual encoding, then re-encode the archive accordingly.
- Patch/extend the legacy decoder (LEGACY_NAME_DECODER) with the correct TextDecoder label for the archive's origin codepage before decoding.
- As a last resort, extract with cabextract (which handles codepage heuristics) and repackage.
Example fix
// before: legacy JP codepage CAB fails decodeName await readCabArchive(buffer); // Invalid CAB archive: file name is not valid UTF-8 // after: repackage with UTF-8-safe names // $ cabextract old.cab && (cd old/ && find . -type f | LC_ALL=C.UTF-8 tar ... ) // or rebuild: lcab --utf8 renamed-ascii-files/ new.cab
Defensive patterns
Strategy: validation
Validate before calling
// Spot-check that the producer emits UTF-8-safe names before distributing the CAB
const names = listEntryNamesRaw(cabBytes); // your own raw-name extraction
for (const n of names) {
new TextDecoder('utf-8', { fatal: true }).decode(n); // throws if not UTF-8
} Type guard
function isValidUtf8(bytes: Uint8Array): boolean {
try { new TextDecoder('utf-8', { fatal: true }).decode(bytes); return true; }
catch { return false; }
} Try / catch
try {
return await readCabArchive(bytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('not valid UTF-8')) {
throw new Error('CAB entry names use a legacy codepage — re-create the archive with UTF-8 names');
}
throw err;
} Prevention
- Standardize on ASCII or UTF-8 entry names when building CABs.
- Know the locale/codepage of machines that produce your CABs.
- Reject non-UTF-8 archives at ingestion rather than mid-extraction.
- Document codepage requirements for archive producers in your pipeline.
When it happens
Trigger: fileTable() iterating CFFILE entries whose szFile bytes are not valid UTF-8 when the CAB declares utf-8 naming, or not decodable in the legacy codepage fallback.
Common situations: CABs created by legacy Windows tools using codepage-encoded names (CP932/CP1251) that neither decode as UTF-8 nor as the configured legacy decoder; a hand-crafted or corrupted archive with random bytes in the name field; mixing archives built on different locale Windows machines.
Related errors
- Invalid CPIO archive: symlink '${recordPath}' has an invalid
- Invalid RPM package: tag ${tag} is not valid UTF-8
- invalid utf-8 sequence
- invalid byte sequence: {:02x?}
- Failed to encode ASAR archive: ${describeError(error)}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/485fcb6d5f7ff0a6.
Report an issue: GitHub.