{"record":{"id":"cab9bd7a4e4a72f1","repo":"can1357/oh-my-pi","slug":"encrypted-zip-member-memberpath-is-not-suppor","errorCode":null,"errorMessage":"Encrypted ZIP member '${memberPath}' is not supported","messagePattern":"Encrypted ZIP member '(.+?)' is not supported","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/zip.ts","lineNumber":393,"sourceCode":"\t\tflags: number,\n\t\tcrc: number,\n\t\tlocalHeaderOffset: number,\n\t\tlimits: ArchiveLimits,\n\t) {\n\t\tthis.#source = source;\n\t\tthis.#compressedSize = compressedSize;\n\t\tthis.#method = method;\n\t\tthis.#flags = flags;\n\t\tthis.#crc = crc;\n\t\tthis.#localHeaderOffset = localHeaderOffset;\n\t\tthis.#limits = limits;\n\t}\n\n\tasync read(size: number, memberPath: string): Promise<Uint8Array> {\n\t\ttry {\n\t\t\tassertArchiveMemberSize(Math.max(size, this.#compressedSize), memberPath, this.#limits);\n\t\t\tif ((this.#flags & (ENCRYPTED_FLAG | STRONG_ENCRYPTION_FLAG)) !== 0 || this.#method === 99) {\n\t\t\t\tthrow new ArchiveError(`Encrypted ZIP member '${memberPath}' is not supported`);\n\t\t\t}\n\t\t\tif (SUPPORTED_METHODS[this.#method] !== true) {\n\t\t\t\tthrow new ArchiveError(`Unsupported ZIP compression method ${this.#method} for '${memberPath}'`);\n\t\t\t}\n\t\t\tconst headerEnd = checkedEnd(\n\t\t\t\tthis.#localHeaderOffset,\n\t\t\t\t30,\n\t\t\t\tthis.#source.size,\n\t\t\t\t`local header for '${memberPath}'`,\n\t\t\t);\n\t\t\tconst header = await this.#source.read(this.#localHeaderOffset, headerEnd);\n\t\t\tif (header.byteLength !== 30 || readUInt32LE(header, 0) !== LOCAL_HEADER_SIGNATURE) {\n\t\t\t\tthrow new ArchiveError(`Invalid ZIP archive: malformed local header for '${memberPath}'`);\n\t\t\t}\n\t\t\tconst localFlags = readUInt16LE(header, 6);\n\t\t\tif ((localFlags & (ENCRYPTED_FLAG | STRONG_ENCRYPTION_FLAG)) !== 0) {\n\t\t\t\tthrow new ArchiveError(`Encrypted ZIP member '${memberPath}' is not supported`);\n\t\t\t}","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/zip.ts#L375-L411","documentation":"The ZIP member is encrypted: either the general-purpose bit flags carry the encrypted (bit 0) or strong-encryption (bit 6) marker, or the compression method is 99 (AES). This library does not implement ZIP decryption, so it refuses to read the member rather than returning ciphertext.","triggerScenarios":"Calling read/extract on a member whose central-directory flags include ENCRYPTED_FLAG (0x1) or STRONG_ENCRYPTION_FLAG (0x40), or whose method is 99 (AES encryption).","commonSituations":"Password-protected ZIPs created by WinZip/7-Zip with AES-256, legacy ZipCrypto archives, secure export pipelines that encrypt archives by default.","solutions":["Decrypt the archive first with an external tool: 7z x -p<password> archive.zip or unzip -P <password> (ZipCrypto only).","Recreate the archive without encryption if the password is unnecessary (zip -e removed; plain zip -r).","If you control the workflow, encrypt at the transport/storage layer (age, openssl enc) instead of inside the ZIP so the library can read members.","If you need in-library decryption, decrypt via a separate step and feed the plaintext archive to this parser."],"exampleFix":"// before\n// const data = await zip.read('secret.txt'); // throws: encrypted\n// after\n// await $`7z x -p${password} -o${outdir} archive.zip`.quiet().nothrow();\n// const data = await Bun.file(`${outdir}/secret.txt`).bytes();","handlingStrategy":"try-catch","validationCode":"import { $ } from \"bun\";\nconst res = await $`7z l -slt archive.zip`.quiet().nothrow();\nif (res.exitCode === 0 && (await res.text()).includes(\"Encrypted = +\")) {\n  throw new Error(\"archive is encrypted; prompt for password before reading\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await archive.readMember(path);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.startsWith(\"Encrypted ZIP member\")) {\n    // decrypt via external tool with user-supplied password, then retry\n    await $`7z x -p${password} -o${outdir} archive.zip`.quiet().nothrow();\n    return await Bun.file(`${outdir}/${path}`).bytes();\n  } else throw err;\n}","preventionTips":["Detect encryption up front (7z l -slt shows 'Encrypted = +') and collect a password before processing.","Prefer transport/storage-layer encryption over ZIP-internal encryption in automated pipelines.","Never assume unattended access to password-protected ZIPs."],"tags":["zip","encryption","unsupported-feature","security"],"backgroundTag":"encrypted-zip-unsupported","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}