can1357/oh-my-pi · error
GPT-5 Harmony leak recurred after truncate-and-resume recove
Error message
GPT-5 Harmony leak recurred after truncate-and-resume recovery (${signalListLabel(err.detection.signals)}). What it means
When the GPT-5 model leaks Harmony-format markup into its output, the agent loop attempts a truncate-and-resume recovery (replacing the leaked assistant message and resuming). This error is thrown after that recovery has succeeded twice already within the window (harmonyTruncateResumeCount >= 2): the leak keeps recurring, so the loop escalates instead of continuing to paper over it. The message lists the detection signals that identified the leak.
Source
Thrown at packages/agent/src/agent-loop.ts:1274
signal,
stream,
telemetry,
invokeAgentSpan,
stepCounter,
streamFn,
harmonyRetryAttempt,
hostToolChoice,
softRequirementState.forcedToolChoice,
preparedProviderCall,
);
harmonyRetryAttempt = 0;
harmonyTruncateResumeCount = 0;
} catch (err) {
if (!(err instanceof HarmonyLeakInterruption)) throw err;
if (err.recovered) {
if (harmonyTruncateResumeCount >= 2) {
await emitHarmonyAudit(config, err, "escalated", harmonyRetryAttempt);
throw new Error(
`GPT-5 Harmony leak recurred after truncate-and-resume recovery (${signalListLabel(err.detection.signals)}).`,
);
}
harmonyTruncateResumeCount++;
recovered = err.recovered;
message = recovered.message;
await emitHarmonyAudit(config, err, "truncate_resume", harmonyRetryAttempt);
// A recovered message completes the turn, so the abort-retry counter
// resets like the normal success path (the truncate-resume counter
// keeps accumulating for its cross-turn cap).
harmonyRetryAttempt = 0;
} else {
if (harmonyRetryAttempt >= 2) {
await emitHarmonyAudit(config, err, "escalated", harmonyRetryAttempt);
throw new Error(
`GPT-5 Harmony leak persisted after ${harmonyRetryAttempt} retries (${signalListLabel(err.detection.signals)}).`,
);
}View on GitHub (pinned to 9690622007)
Solutions
- Switch to a different model or model snapshot that does not leak Harmony tokens.
- Review/adjust the system prompt for content that induces the model to echo its chat template.
- If this is a provider-side regression, report it; meanwhile pin a known-good model revision via the catalog config.
- Temporarily raise the truncate-resume cap only if continued degraded output is preferable to failing the turn.
Example fix
// before
const agent = createAgent({ model: "gpt-5-preview-0902" });
// after
const agent = createAgent({ model: "gpt-5" }); // known-good revision; or catch and fall back:
try {
await runAgent(agent);
} catch (err) {
if (String(err).includes("Harmony leak recurred")) await runAgent(fallbackAgent);
else throw err;
} Defensive patterns
Strategy: retry
Type guard
function isHarmonyLeakEscalation(err: unknown): err is Error {
return err instanceof Error && err.message.includes("Harmony leak recurred after truncate-and-resume");
} Try / catch
try {
await runTurn();
} catch (err) {
if (isHarmonyLeakEscalation(err)) {
await runTurn({ model: fallbackModel }); // retry with a non-leaking model
} else {
throw err;
}
} Prevention
- Pin a model revision known not to leak Harmony tokens.
- Monitor harmony audit events ('truncate_resume' emissions) as an early signal before escalation.
- Avoid prompt content that induces template echo in GPT-5-class models.
- Configure a fallback model for automatic recovery on escalation.
When it happens
Trigger: Streaming an assistant response from a GPT-5-class model where HarmonyLeakInterruption with recovered=true is raised on the third occurrence within the cap — i.e. the model repeatedly emits Harmony tokens (<|start|>, channel markers, etc.) even after two truncate-and-resume recoveries.
Common situations: A specific model snapshot/revision regressed into emitting its internal chat template; aggressive system prompts or few-shot content that triggers template echo; misrouted model IDs hitting a Harmony-trained model without the provider-side template stripping.
Related errors
- GPT-5 Harmony leak persisted after ${harmonyRetryAttempt} re
- inspect_image model returned no text output.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e3ea3a10a0f14e14.
Report an issue: GitHub.