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

  1. Convert base64 strings to bytes first: `Uint8Array.fromBase64(str)` (or an atob-based fallback), and hex strings via a hex decode helper.
  2. Wrap ArrayBuffer/DataView: `new Uint8Array(buffer)`; for number arrays: `Uint8Array.from(arr)`.
  3. Ensure Buffer values are genuine Uint8Array views (`new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength)` if crossing realms).
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/fa6f879e4a8cbbda. Report an issue: GitHub.