Skip to content

compaction.auto: false does not disable V2 overflow recovery #44991

Closed

Description

@altendky

Description

V2 treats compaction.auto: false as disabling only the preflight context-pressure check. If the provider instead reports context-overflow before producing output, the runner still generates a compaction summary and retries the step.

This is current behavior in packages/core, not the removed legacy runtime:

const required = (input: RequiredInput) => {
const config = state.get()
if (!config.auto) return false
const limit = input.resolved.limit
const context = limit.context
if (context <= 0) return false
const last = input.messages.findLast(
(message): message is SessionMessage.Assistant & { tokens: NonNullable<SessionMessage.Assistant["tokens"]> } =>
message.type === "assistant" && message.tokens !== undefined,
)
if (!last) return false
const output = Math.min(limit.output, OUTPUT_TOKEN_MAX)
const promptCeiling = Math.min(
limit.input === undefined ? Number.POSITIVE_INFINITY : limit.input - config.buffer,
context - Math.max(output, config.buffer),
)
const used =
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
if (used <= 0) return false
return used >= promptCeiling
}

// A context overflow before any assistant output is recoverable: compact and
// restart the step instead of surfacing the provider error.
if (
recoverOverflow &&
!publisher.record().outputStarted &&
isContextOverflowFailure(overflowFailure ?? streamFailure) &&
(yield* restore(compaction.compact(compactionInput))).status === "completed"
)
return CallOutcome.Restart({ step: currentStep, recoveredOverflow: true })

PR #31005 made this intentional, stating that overflow recovery bypasses:

compaction.auto: false, because this path recovers an otherwise terminal provider failure.

That recovery should remain enabled by default. The contract problem is explicit false: a user who disables automatic compaction should receive the provider error for that attempt rather than another automatic, lossy model call.

The error ends only the current attempt with the current model; it does not make the session unusable. The user can switch to a model with a larger context window, compact manually, or otherwise decide how to proceed while preserving the existing context.

The same discrepancy was reported for the legacy runtime in #16882 and fixed by #30749. This is a separate V2 issue because #31005 later introduced the opposite behavior in packages/core.

Expected behavior:

  • auto omitted or true: preserve the current one-shot overflow recovery.
  • auto: false: surface the original overflow without a summary request, compaction event, or rebuilt attempt.
  • Manual compaction remains available.

The proposed scope is the V2 recovery gate, focused runner coverage, and the corresponding docs/spec correction. It does not add or rename configuration fields.

@kitlangton and @nexxeln, you implemented the two sides of this history in #31005 and #30749. Could you confirm whether aligning V2 with the explicit opt-out contract is the intended resolution?

Plugins

None

OpenCode version

V2 development branch at 5963a30

Steps to reproduce

  1. Configure { "compaction": { "auto": false } }.
  2. Create a V2 session with enough prior history for compaction.
  3. Have the provider return an error classified as context-overflow before assistant output begins.
  4. Observe that V2 issues a summary request and rebuilds the logical step.

Expected: the original overflow is persisted as the failure for that attempt, without automatic compaction or retry.

Screenshot and/or share link

Not applicable; this is core session-runner behavior rather than a UI-specific failure.

Operating System

Linux; the behavior is in the platform-independent V2 session runner.

Terminal

N/A (core runner behavior)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions