can1357/oh-my-pi · error · Error
Expected Uint8Array
Error message
Expected Uint8Array
What it means
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.
Source
Thrown at packages/catalog/src/discovery/protobuf.ts:641
return getCodec().decode(reader.bytes());
},
toJson(value) {
return getCodec().toJson(value);
},
isDefault(value) {
return value === undefined;
},
};
}
function requireBoolean(value: unknown): boolean {
if (typeof value === "boolean") return value;
throw new Error(`Expected boolean, got ${typeof value}`);
}
function requireBytes(value: unknown): Uint8Array {
if (value instanceof Uint8Array) return value;
throw new Error("Expected Uint8Array");
}
function requireNumber(value: unknown): number {
if (typeof value === "number" && Number.isFinite(value)) return value;
throw new Error(`Expected number, got ${typeof value}`);
}
function requireInt32(value: unknown): number {
if (typeof value === "number" && Number.isInteger(value)) return value | 0;
throw new Error(`Expected int32, got ${typeof value}`);
}
function requireString(value: unknown): string {
if (typeof value === "string") return value;
throw new Error(`Expected string, got ${typeof value}`);
}
function requireBigInt(value: unknown): bigint {
if (typeof value === "bigint") return value;View on GitHub (pinned to 9690622007)
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"`.
Example fix
// before
const msg = Msg.create({ digest: sha256Hex(data) }); // hex string
// after
const bytes = Uint8Array.fromBase64(sha256Base64(data)); // or decodeHex helper
const msg = Msg.create({ digest: bytes }); Defensive patterns
Strategy: validation
Validate before calling
function toBytes(v: unknown): Uint8Array {
if (v instanceof Uint8Array) return v;
if (typeof v === "string") return Uint8Array.fromBase64(v); // protobuf-JSON base64 form
if (v instanceof ArrayBuffer) return new Uint8Array(v);
if (Array.isArray(v)) return Uint8Array.from(v);
throw new TypeError(`bytes field expects Uint8Array/base64 string, got ${typeof v}`);
} Type guard
function isBytes(v: unknown): v is Uint8Array {
return v instanceof Uint8Array;
} Try / catch
try {
return MyMsg.encode(value);
} catch (err) {
if (err instanceof Error && err.message === "Expected Uint8Array") {
throw new TypeError(`bytes field '${fieldName}' must be a Uint8Array (not a base64/hex string or Buffer-like value)`);
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Expected boolean, got ${typeof value}
- Expected number, got ${typeof value}
- Expected int32, got ${typeof value}
- Unsupported protobuf wire type ${wireType} at byte ${reader.
- Unsupported wire type ${entryWireType} in map entry
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/fa6f879e4a8cbbda.
Report an issue: GitHub.