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
- Call the `rewrite` tool (or `protocol.submit(text, losses)`) to record a draft first
- Re-run the compress session from the start so the agent produces a draft before approving
- 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
- Check `protocol.rounds > 0` before any approve call
- Drive the tools strictly in rewrite → review → approve order
- Never expose `approve` to the agent until at least one draft exists
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
- Draft ${draft.round} has not been reviewed yet. End this tur
- Replacement text is not valid UTF-8: {err}
- invalid glob `{pattern}`: {error}
- Cannot continue from message role: assistant
- V2 compaction expected exactly one compaction output item, g
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a38967f65a7f4774.
Report an issue: GitHub.