can1357/oh-my-pi · error

Call rewrite before approve: there is no draft to accept

Error message

Call rewrite before approve: there is no draft to accept

What it means

`CompressProtocol.accept()` throws this when `approve` is called before any `rewrite` call has submitted a draft. The compress protocol requires a draft to exist before a verdict can be recorded; with an empty draft ledger there is nothing to approve. It is a strict ordering guard for the two-tool rewrite/approve flow.

Source

Thrown at packages/coding-agent/src/compress/protocol.ts:159

			round: this.#drafts.length + 1,
			text,
			losses: losses.map(loss => ({ content: loss.content, reason: loss.reason })),
		};
		this.#drafts.push(draft);
		this.#approved = false;
		this.#verdict = undefined;
		return draft;
	}

	/**
	 * Accept the newest draft and return it.
	 *
	 * Throws when no draft exists, or when the newest draft has not been shown back
	 * to the agent for a verdict — approval is only meaningful after that review.
	 */
	accept(verdict: string): CompressDraft {
		const draft = this.latest;
		if (!draft) throw new Error("Call rewrite before approve: there is no draft to accept");
		if (draft.round > this.#reviewed) {
			throw new Error(
				`Draft ${draft.round} has not been reviewed yet. End this turn; the review turn arrives next, and you approve there.`,
			);
		}
		this.#approved = true;
		this.#verdict = verdict;
		return draft;
	}

	/** Tool that records a draft. Thin adapter over {@link submit}. */
	rewriteTool(): ToolDefinition {
		return {
			name: "rewrite",
			label: "Rewrite",
			description: rewriteDescription.trim(),
			parameters: rewriteSchema,
			approval: "read",

View on GitHub (pinned to 9690622007)

Solutions

  1. Call the `rewrite` tool (or `protocol.submit(text, losses)`) to record a draft first
  2. Re-run the compress session from the start so the agent produces a draft before approving
  3. Check `protocol.latest` / `protocol.rounds` before calling `accept` to confirm a draft exists

Example fix

// before
protocol.accept("looks good"); // throws: no draft
// after
protocol.submit(compressedText, losses);
protocol.markReviewed(1);
protocol.accept("losses are acceptable");
Defensive patterns

Strategy: validation

Validate before calling

if (!protocol.latest) throw new Error("Cannot approve before rewrite submits a draft");

Type guard

function hasDraft(p: CompressProtocol): p is CompressProtocol & { latest: CompressDraft } { return p.latest !== undefined; }

Try / catch

try {
  protocol.accept(verdict);
} catch (err) {
  if (err instanceof Error && err.message.includes("no draft to accept")) {
    // submit a rewrite first, then approve
  } else throw err;
}

Prevention

When it happens

Trigger: Calling `protocol.accept(verdict)` (or the `approve` tool) on a fresh `CompressProtocol` instance before any `rewrite`/`submit()` call has been made.

Common situations: An agent skips the rewrite step and goes straight to approve because it misreads the tool descriptions; a driver script invokes approve first; a session is replayed with a protocol instance that lost its draft state.

Related errors


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