can1357/oh-my-pi · error · SyntaxError

Unterminated array

Error message

Unterminated array

What it means

Thrown by RelaxedJson.#array in strict mode when end-of-input is reached while still inside an array — no closing ']' was found. In partial (streaming) mode the array is auto-closed with the elements parsed so far; in strict mode it throws so truncated JSON fails loudly.

Source

Thrown at packages/utils/src/json-parse.ts:310

				continue;
			}
			if (d === "}") {
				this.#i++;
				return out;
			}
			if (this.#partial) return out;
			throw new SyntaxError("Expected ',' or '}' in object");
		}
	}

	#array(): unknown[] {
		this.#i++; // consume [
		const out: unknown[] = [];
		for (;;) {
			this.#ws();
			if (this.#i >= this.#n) {
				if (this.#partial) return out;
				throw new SyntaxError("Unterminated array");
			}
			const c = this.#s[this.#i];
			if (c === "]") {
				this.#i++;
				return out;
			}
			if (c === ",") {
				this.#i++;
				continue;
			}
			const value = this.#value(true);
			if (value === INCOMPLETE) return out;
			out.push(value);
			this.#ws();
			const d = this.#i < this.#n ? this.#s[this.#i] : "";
			if (d === ",") {
				this.#i++;
				continue;

View on GitHub (pinned to 9690622007)

Solutions

  1. Read/await the complete payload before parsing
  2. Use parseStreamingJson for incomplete streaming input — it returns the array parsed so far
  3. Use classifyJsonPrefix to confirm the buffer is a 'prefix' and wait for more data instead of final-parsing
  4. Re-fetch the payload if the transport truncated it

Example fix

// before
const v = parseJsonWithRepair<number[]>(`[1, 2`); // SyntaxError
// after
const v = parseStreamingJson<number[]>(`[1, 2`); // [1, 2]
Defensive patterns

Strategy: validation

Validate before calling

import { classifyJsonPrefix } from "@oh-my-pi/pi-utils/json-parse";
if (classifyJsonPrefix(text) === "complete") {
  // safe to final-parse; 'prefix' means the array may still be receiving elements
}

Try / catch

try {
  const value = parseJsonWithRepair<T>(text);
} catch (err) {
  if (err instanceof SyntaxError && err.message === "Unterminated array") {
    const partial = parseStreamingJson<T>(text); // auto-closed array so far
  } else throw err;
}

Prevention

When it happens

Trigger: parseJsonWithRepair with '[1, 2', '[', or '[1,' — any input ending inside an array body when this.#partial is false.

Common situations: Truncated LLM tool-call arguments (token limit); a file or HTTP body read incompletely; log truncation cutting the tail of the payload.

Related errors


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