{"record":{"id":"a4a737ce56ea10b6","repo":"can1357/oh-my-pi","slug":"asar-members-must-be-path-uint8array-pairs","errorCode":null,"errorMessage":"ASAR members must be [path, Uint8Array] pairs","messagePattern":"ASAR members must be \\[path, Uint8Array\\] pairs","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/asar.ts","lineNumber":417,"sourceCode":"\t\tthrow new ArchiveError(`Invalid ASAR member path '${formatArchivePathForError(rawPath)}'`);\n\t}\n\treturn normalized;\n}\n\n/** Encode file members in Electron's Pickle-framed ASAR layout. */\nexport async function encodeAsar(members: Iterable<readonly [string, Uint8Array]>): Promise<Uint8Array> {\n\ttry {\n\t\tconst root: AsarDirectoryNode = { files: Object.create(null) as Record<string, AsarNode> };\n\t\tconst payloads: Uint8Array[] = [];\n\t\tlet payloadSize = 0;\n\t\tfor (const member of members) {\n\t\t\tif (\n\t\t\t\t!Array.isArray(member) ||\n\t\t\t\tmember.length !== 2 ||\n\t\t\t\ttypeof member[0] !== \"string\" ||\n\t\t\t\t!(member[1] instanceof Uint8Array)\n\t\t\t) {\n\t\t\t\tthrow new ArchiveError(\"ASAR members must be [path, Uint8Array] pairs\");\n\t\t\t}\n\t\t\tconst memberPath = writerPath(member[0]);\n\t\t\tconst parts = memberPath.split(\"/\");\n\t\t\tlet directory = root;\n\t\t\tfor (let index = 0; index < parts.length - 1; index++) {\n\t\t\t\tconst part = parts[index]!;\n\t\t\t\tconst existing = directory.files[part];\n\t\t\t\tif (existing && !(\"files\" in existing)) {\n\t\t\t\t\tthrow new ArchiveError(\n\t\t\t\t\t\t`ASAR member path '${memberPath}' crosses file '${parts.slice(0, index + 1).join(\"/\")}'`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!existing) {\n\t\t\t\t\tdirectory.files[part] = { files: Object.create(null) as Record<string, AsarNode> };\n\t\t\t\t}\n\t\t\t\tdirectory = directory.files[part] as AsarDirectoryNode;\n\t\t\t}\n\t\t\tconst name = parts.at(-1)!;","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/asar.ts#L399-L435","documentation":"Thrown by encodeAsar when an item yielded by the members iterable is not a [string, Uint8Array] tuple: not an array, wrong length, non-string path, or non-Uint8Array payload. It is an input-shape contract check before any path validation.","triggerScenarios":"Passing objects instead of tuples ({path, data}), 3-element arrays, Node Buffer is fine only if it's a Uint8Array subclass (it is), but strings/ArrayBuffers/blob handles as payloads are rejected; iterables of Maps or entries from Object.entries with reordered fields.","commonSituations":"Collecting files with an async mapper that accidentally returns [path, string] after text decoding; passing PathOrFileRecord-style objects; TypeScript code compiled loosely at runtime boundaries (JSON-parsed input).","solutions":["Ensure every member is exactly a 2-tuple: [relativePath: string, payload: Uint8Array]","Convert string payloads with new TextEncoder().encode(text) and ArrayBuffer with new Uint8Array(buf)","If input is object-shaped, map it to tuples: Object.entries(map).map(([p, d]) => [p, d])"],"exampleFix":"// before\nencodeAsar([{ path: \"a.txt\", data: \"hello\" }])\n// after\nencodeAsar([[\"a.txt\", new TextEncoder().encode(\"hello\")]])","handlingStrategy":"type-guard","validationCode":"const toMembers = (input) => Object.entries(input).map(([p, d]) => [p, d instanceof Uint8Array ? d : new TextEncoder().encode(String(d))]);","typeGuard":"const isAsarMember = (m) => Array.isArray(m) && m.length === 2 && typeof m[0] === \"string\" && m[1] instanceof Uint8Array;","tryCatchPattern":"try { return await encodeAsar(rawMembers); } catch (e) { if (e instanceof ArchiveError && e.message.includes(\"must be [path, Uint8Array] pairs\")) { console.error(\"normalize member tuples before encoding\"); } throw e; }","preventionTips":["Encode string contents with TextEncoder before passing to encodeAsar","Keep member collections as [string, Uint8Array] tuples end to end","Type the input as Iterable<readonly [string, Uint8Array]> so TS catches mistakes at compile time"],"tags":["asar","type-mismatch","validation","encoding"],"backgroundTag":"invalid-argument-type","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}