{"record":{"id":"fa6f879e4a8cbbda","repo":"can1357/oh-my-pi","slug":"expected-uint8array","errorCode":null,"errorMessage":"Expected Uint8Array","messagePattern":"Expected Uint8Array","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/catalog/src/discovery/protobuf.ts","lineNumber":641,"sourceCode":"\t\t\treturn getCodec().decode(reader.bytes());\n\t\t},\n\t\ttoJson(value) {\n\t\t\treturn getCodec().toJson(value);\n\t\t},\n\t\tisDefault(value) {\n\t\t\treturn value === undefined;\n\t\t},\n\t};\n}\n\nfunction requireBoolean(value: unknown): boolean {\n\tif (typeof value === \"boolean\") return value;\n\tthrow new Error(`Expected boolean, got ${typeof value}`);\n}\n\nfunction requireBytes(value: unknown): Uint8Array {\n\tif (value instanceof Uint8Array) return value;\n\tthrow new Error(\"Expected Uint8Array\");\n}\n\nfunction requireNumber(value: unknown): number {\n\tif (typeof value === \"number\" && Number.isFinite(value)) return value;\n\tthrow new Error(`Expected number, got ${typeof value}`);\n}\n\nfunction requireInt32(value: unknown): number {\n\tif (typeof value === \"number\" && Number.isInteger(value)) return value | 0;\n\tthrow new Error(`Expected int32, got ${typeof value}`);\n}\nfunction requireString(value: unknown): string {\n\tif (typeof value === \"string\") return value;\n\tthrow new Error(`Expected string, got ${typeof value}`);\n}\n\nfunction requireBigInt(value: unknown): bigint {\n\tif (typeof value === \"bigint\") return value;","sourceCodeStart":623,"sourceCodeEnd":659,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/catalog/src/discovery/protobuf.ts#L623-L659","documentation":"Thrown by requireBytes, the validator for the `bytes` scalar kind. It rejects any value that is not an actual `Uint8Array` instance when encoding, converting to JSON, or checking defaults for a bytes-typed field. Notably it does not accept plain strings — unlike the protobuf JSON mapping (where bytes are base64 strings), the wire encoder here requires raw bytes and only produces base64 on the toJson side (`value.toBase64()`). The message is a constant, so debugging relies on knowing which field was being encoded.","triggerScenarios":"Specific: passing a base64 string to a bytes field (the JSON representation, not the wire-representation input); passing a Node `Buffer` compiled against a runtime where Buffer is not `instanceof Uint8Array` (or an ArrayBuffer/DataView); passing a hex string or number[] array of byte values; a descriptor declaring `\"bytes\"` for a field populated with a string ID; calling `toJson` on a message whose bytes field was hand-set to a string.","commonSituations":"Real-world: round-tripping through protobuf JSON and feeding the base64 string back into encode; reading a file/hash with an API that returns ArrayBuffer; cross-realm Uint8Array (vm/worker boundary) failing `instanceof`; older code using Buffer where the instance check still holds in Bun/Node but a string slipped through from config.","solutions":["Convert base64 strings to bytes first: `Uint8Array.fromBase64(str)` (or an atob-based fallback), and hex strings via a hex decode helper.","Wrap ArrayBuffer/DataView: `new Uint8Array(buffer)`; for number arrays: `Uint8Array.from(arr)`.","Ensure Buffer values are genuine Uint8Array views (`new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength)` if crossing realms).","Fix the descriptor if the field is semantically textual — use `\"string\"` instead of `\"bytes\"`."],"exampleFix":"// before\nconst msg = Msg.create({ digest: sha256Hex(data) }); // hex string\n// after\nconst bytes = Uint8Array.fromBase64(sha256Base64(data)); // or decodeHex helper\nconst msg = Msg.create({ digest: bytes });","handlingStrategy":"validation","validationCode":"function toBytes(v: unknown): Uint8Array {\n  if (v instanceof Uint8Array) return v;\n  if (typeof v === \"string\") return Uint8Array.fromBase64(v); // protobuf-JSON base64 form\n  if (v instanceof ArrayBuffer) return new Uint8Array(v);\n  if (Array.isArray(v)) return Uint8Array.from(v);\n  throw new TypeError(`bytes field expects Uint8Array/base64 string, got ${typeof v}`);\n}","typeGuard":"function isBytes(v: unknown): v is Uint8Array {\n  return v instanceof Uint8Array;\n}","tryCatchPattern":"try {\n  return MyMsg.encode(value);\n} catch (err) {\n  if (err instanceof Error && err.message === \"Expected Uint8Array\") {\n    throw new TypeError(`bytes field '${fieldName}' must be a Uint8Array (not a base64/hex string or Buffer-like value)`);\n  }\n  throw err;\n}","preventionTips":["Treat base64 strings as a JSON-format concern only; always convert to Uint8Array before encode.","Normalize ArrayBuffer/DataView/Buffer values to `new Uint8Array(...)` views at the boundary.","Keep a small `toBytes()` coercion helper in shared utils and use it for every bytes field.","Prefer \"string\" in the descriptor when the data is actually textual."],"tags":["protobuf","type-validation","bytes","encode"],"backgroundTag":"unexpected-field-type","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}