can1357/oh-my-pi · error

data too long for a QR code (${data.length} bytes, EC ${ecLe

Error message

data too long for a QR code (${data.length} bytes, EC ${ecLevel})

What it means

encodeBytes walks QR versions up to maxVersion looking for one whose data capacity fits the payload; if even the maximum version with the chosen error-correction level cannot hold the bytes, it throws a descriptive length error.

Source

Thrown at packages/coding-agent/src/utils/qrcode.ts:196

	/** Encode a string in byte mode (UTF-8). Throws if it exceeds version 40. */
	static encodeText(text: string, ecLevel: QrEcLevel = "M", options?: QrEncodeOptions): QrCode {
		return QrCode.encodeBytes(new TextEncoder().encode(text), ecLevel, options);
	}

	/** Encode raw bytes in byte mode. Throws if they exceed version 40 at this EC level. */
	static encodeBytes(data: Uint8Array, ecLevel: QrEcLevel = "M", options?: QrEncodeOptions): QrCode {
		const ec = EC_LEVELS[ecLevel];
		const minVersion = Math.max(MIN_VERSION, options?.minVersion ?? MIN_VERSION);
		const maxVersion = Math.min(MAX_VERSION, options?.maxVersion ?? MAX_VERSION);

		let version = minVersion;
		for (; ; version++) {
			const capacityBits = dataCodewords(version, ec.table) * 8;
			const usedBits = 4 + charCountBits(version) + data.length * 8;
			if (usedBits <= capacityBits) break;
			if (version >= maxVersion) {
				throw new Error(`data too long for a QR code (${data.length} bytes, EC ${ecLevel})`);
			}
		}

		const bits = new BitBuffer();
		bits.append(BYTE_MODE_INDICATOR, 4);
		bits.append(data.length, charCountBits(version));
		for (const b of data) bits.append(b, 8);

		const capacityBits = dataCodewords(version, ec.table) * 8;
		bits.append(0, Math.min(4, capacityBits - bits.length)); // terminator
		bits.append(0, (8 - (bits.length % 8)) % 8); // byte-align
		for (let pad = 0; bits.length < capacityBits; pad ^= 1) bits.append(PAD_BYTES[pad]!, 8);

		const codewords = QrCode.#interleave(bits.toBytes(), version, ec.table);
		const mask = options?.mask ?? -1;
		if (mask < -1 || mask > 7) throw new Error(`invalid mask ${mask}`);
		return new QrCode(version, ecLevel, codewords, mask);
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Shorten the payload (URL shortener, trim fields, drop optional data).
  2. Lower the error-correction level (H to Q to M to L) to gain capacity.
  3. Split the data across multiple QR codes or use a different transport.
  4. If the library exposes it, increase maxVersion — otherwise the data physically cannot fit one QR code.

Example fix

// before: encodeBytes(longVCard, { ecLevel: "H" }); // 2KB payload  // after: shorten the payload (or use ecLevel "L"), then encodeBytes(shortened, { ecLevel: "L" });
Defensive patterns

Strategy: validation

Validate before calling

const MAX_BYTES = { L: 2953, M: 2331, Q: 1663, H: 1273 } as const; if (payload.length > MAX_BYTES[ecLevel]) throw new Error(`payload too long for QR at EC ${ecLevel}`);

Try / catch

try { const qr = encodeBytes(data, { ecLevel }); } catch (err) { if (err instanceof Error && err.message.startsWith("data too long")) { return encodeBytes(shorten(data), { ecLevel: "L" }); } throw err; }

Prevention

When it happens

Trigger: Calling the QR encoder (encodeBytes) with data longer than the maximum QR version's byte capacity at the given EC level — e.g. more than ~1,273 bytes at EC H, or ~2,953 bytes at EC L in byte mode.

Common situations: Encoding long URLs with huge query strings, vCards with many fields, Wi-Fi payloads with long keys, or embedding a file/blob into a QR code.

Related errors


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