{"record":{"id":"40e27d1e730d9ac9","repo":"can1357/oh-my-pi","slug":"error-instanceof-error-error-message-string","errorCode":null,"errorMessage":"${error instanceof Error ? error.message : String(error)}","messagePattern":"\\$\\{error instanceof Error \\? error\\.message : String\\(error\\)\\}","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/lzw.ts","lineNumber":189,"sourceCode":"\t\t\tneedsPreviousSuffix = false;\n\t\t}\n\t}\n}\n\n/** Return whether bytes begin with the ncompress `.Z` magic number. */\nexport function isCompressZ(bytes: Uint8Array): boolean {\n\treturn bytes.byteLength >= 2 && bytes[0] === 0x1f && bytes[1] === 0x9d;\n}\n\n/** Decompress an ncompress `.Z` stream while enforcing a hard output bound. */\nexport async function lzwDecompress(bytes: Uint8Array, maxOutput: number): Promise<Uint8Array> {\n\ttry {\n\t\treturn decode(bytes, maxOutput);\n\t} catch (error) {\n\t\tif (error instanceof ArchiveError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new ArchiveError(error instanceof Error ? error.message : String(error));\n\t}\n}\n","sourceCodeStart":171,"sourceCodeEnd":192,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/lzw.ts#L171-L192","documentation":"lzwDecompress wraps the internal decode() and normalizes any non-ArchiveError exception (RangeError from typed arrays, TypeErrors, etc.) into an ArchiveError carrying the original message. Hitting this wrapper means an unexpected runtime exception escaped decode() — usually caused by invalid argument types rather than corrupt stream content (which already throws typed ArchiveErrors).","triggerScenarios":"Calling lzwDecompress with a non-integer or negative maxOutput (NaN, undefined coerced, Infinity), passing a non-Uint8Array view (Buffer is fine, but a DataView or plain array is not), or a typed-array operation throwing inside decode (e.g. output limit so large that allocation fails).","commonSituations":"maxOutput accidentally left undefined or parsed from config as a string; passing options object fields of the wrong type; wiring the function into generic decompress dispatch that routes formats it cannot handle; OOM-scale maxOutput values.","solutions":["Validate arguments before calling: ensure bytes is a Uint8Array/Buffer and maxOutput is a positive safe integer.","Read the wrapped message in the ArchiveError — it names the underlying cause; fix that specific problem.","If maxOutput comes from config/user input, clamp/parse it (Number.parseInt + Number.isSafeInteger check).","For persistent unexpected errors, reproduce with a minimal input and report; decode() is expected to throw typed ArchiveErrors for stream problems only."],"exampleFix":"// before\nconst limit = config.maxOutput; // possibly \"10485760\" or undefined\nawait lzwDecompress(input, limit);\n// after\nconst limit = Number(config.maxOutput);\nif (!Number.isSafeInteger(limit) || limit <= 0) throw new Error(\"bad maxOutput\");\nawait lzwDecompress(new Uint8Array(input), limit);","handlingStrategy":"validation","validationCode":"function assertDecompressArgs(bytes: unknown, maxOutput: unknown): asserts bytes is Uint8Array {\n  if (!(bytes instanceof Uint8Array)) throw new TypeError(\"bytes must be a Uint8Array/Buffer\");\n  if (!Number.isSafeInteger(maxOutput) || (maxOutput as number) < 0) throw new TypeError(\"maxOutput must be a non-negative safe integer\");\n}","typeGuard":"function isDecompressInput(v: unknown): v is { bytes: Uint8Array; maxOutput: number } {\n  return typeof v === \"object\" && v !== null && v.bytes instanceof Uint8Array && Number.isSafeInteger(v.maxOutput) && v.maxOutput >= 0;\n}","tryCatchPattern":"try {\n  return await lzwDecompress(bytes, maxOutput);\n} catch (e) {\n  if (e instanceof ArchiveError && !(e.message.startsWith(\"Invalid compress\") || e.message.includes(\"Corrupt\") || e.message.includes(\"Truncated\"))) {\n    // wrapped unexpected error: log the underlying message for diagnosis\n    console.error(\"unexpected LZW failure:\", e.message);\n  }\n  throw e;\n}","preventionTips":["Coerce and validate maxOutput (Number.parseInt + Number.isSafeInteger) before calling.","Pass Uint8Array/Buffer only — convert ArrayBuffer/DataView views explicitly.","Set a realistic maxOutput bound (e.g. a few hundred MB) to avoid allocation failures."],"tags":["archive","lzw","argument-validation","error-wrapping"],"backgroundTag":"invalid-decompress-arguments","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}