Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

[Bug]: mcode exec fails with limit_exceeded (exit 7) when auto-compaction runs, because the checkpoint consumes --max-steps

Offen
#514 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
15/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
node.js, typescript
Bereich
backend, cli

Rechercherichtung

Start by reading the listed consumers in packages/tui/src/application/run-coordinator.ts, response-usage.ts, headless/events.ts, acp/updates.ts, and the projection, transcript, and channel adapter files. Trace how assistant lifecycle messages are classified and run the local fixture reproduction with --max-steps 1; done means the checkpoint does not consume a user step or leak as assistant output across the affected consumers. The issue reports an existing fork patch, so check contribution guidance before taking it on.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Product or interface

CLI - headless

Version
  • Source checkout at commit 5821f7c (package.json version 0.6.5, docs/open-source-status.md calls this the 0.6.3 source preview)
  • Node.js 24.9.0, pnpm 9.12.0
  • Affects packages/tui and packages/local-runtime-v2 as shipped in this repository
Platform

Multiple platforms

OS version and architecture

Originally reproduced on Windows x64. The defect is platform-independent: it is a message-classification bug in shared TypeScript, with no platform, filesystem or native dependency involved.

Issue area

Agent stuck / slow / repeated loop

Steps to reproduce

Use a local OpenAI-compatible fixture so no real provider or account is involved. The key requirement is that automatic context compaction triggers during the turn.

  1. Register a provider with a small context window, which lowers the auto-compaction trigger:
mcode provider add --name ctx --base-url http://127.0.0.1:<port>/v1 \
  --api-format openai-completions --model fixture-model \
  --context-limit 32768 --support-image --use
  1. Run a single-turn task with --max-steps 1:
mcode exec "IMAGE_INPUT_TEST" \
  --model custom_provider:ctx/fixture-model \
  --file fixture.png \
  --timeout 20s --max-steps 1

--file only matters because it is one way to push the request over the compaction trigger. Permission mode is irrelevant; the failure happens before the tool loop. No credentials are needed beyond the fixture key.

The same failure occurs with any prompt when the context is near the trigger, e.g. --context-limit 8192 with no attachment at all.

Expected and actual behavior

Expected: --max-steps 1 bounds how many times the agent calls the model for the user's turn. An internal compaction checkpoint is bookkeeping, not a user turn step, so the run should succeed with one model response and report the real answer.

Actual:

mcode exec limit_exceeded: The run reached its step limit. Increase --max-steps or narrow the task.
$ echo $?
7

Diagnostics confirm the first provider request of the turn is the checkpoint, and the real turn is the second request:

{"kind":"model_phase_started","operationId":"turn_...:model:1",...}
# request 1 -> "Checkpoint control: summarize the preceding conversation now. ..."
# request 2 -> the user's actual turn

Deterministic before/after matrix (local fixture, --max-steps 1):

context limit image attachment checkpoint performed result
32768 yes 1 exit 7
32768 no 0 exit 0
8192 yes 0 exit 7
8192 no 0 exit 7

The 8192 rows fail even without a checkpoint because the request alone exceeds the trigger; either way the reported reason is "step limit", which points a user at --max-steps instead of at context compaction.

Same root cause, four additional user-visible effects (all reachable from the same misclassification, see below):

  1. A lifecycle frame can replace an answer that was already selected: answer is cleared and the retained streamed draft is discarded, so the turn can end with no answer or with the checkpoint text.
  2. Compaction content is projected to ACP clients as agent_message_chunk, so an IDE sees checkpoint prose as assistant output.
  3. Compaction checkpoint text renders as the live assistant reply in the TUI and is written into exported Markdown transcripts.
  4. Chat-channel replies (Feishu/Telegram/WeChat) leak compaction and review text, because the collector only filters the terminal kind === 'compaction' state and misses compaction_start, compaction_failed and all review_* frames.
Root cause

Compaction and review lifecycle frames are persisted with role: 'assistant' because they share the message store with model responses. The two facts are orthogonal — role says who produced the frame, kind says which lifecycle state it is — but the repository never defined a single "is this a model response" predicate. Each consumer re-derived it:

Location Predicate Consequence
packages/tui/src/application/run-coordinator.ts role === 'assistant' lifecycle frame consumes a --max-steps slot
packages/tui/src/application/response-usage.ts kind?.startsWith('compaction') review_* contributes usage and response identity
packages/tui/src/headless/events.ts role === 'assistant' checkpoint text becomes agent_message output
packages/tui/src/acp/updates.ts role === 'assistant' checkpoint text sent to IDE clients
packages/tui/src/tui/controller/projection/turn-live-projection.ts none checkpoint text rendered as assistant body
packages/tui/src/tui/transcript/export.ts role only checkpoint text enters exported Markdown
packages/local-runtime/src/channels/sse-collector.ts kind === 'compaction' three of eight lifecycle kinds filtered
packages/local-runtime/src/api/conversation-message-adapter.ts three literal compaction kinds review_* dropped, then re-read as model output

--max-steps is therefore consumed by an internal auxiliary request, and the CLI reports a limit error for a run that never exceeded its intended budget.

Suggested fix

Introduce one classification module and make every producer type and consumer read it, so no alternate path can drift again. In my working tree this is @mavis/shared/turn-message-class (chosen because packages/tui does not depend on @mavis/agent-core, and @mavis/shared sits at the bottom of the dependency graph):

  • lifecycle kind sets and kind → lifecycle-state tables, replacing three separate if/else ladders
  • isTurnResponseMessage(message) = role === 'assistant' && !isTurnLifecycleMessage(message)
  • MessageKind and RuntimeMessageKind derive from the shared union instead of re-listing literals
  • run-coordinator gates response steps, usage and answer selection through one composed predicate; a lifecycle frame is not a step, but still marks usage incomplete because its auxiliary call spends tokens
  • the other eight call sites ask the same module instead of comparing role or kind

A local fix in run-coordinator alone would stop the exit-7 symptom but leave items 2–4 above in place, which is why I am reporting the shared root cause rather than only the step counter.

Redacted error summary
mcode exec limit_exceeded: The run reached its step limit. Increase --max-steps or narrow the task.

Exit code 7, mapped from limit_exceeded in packages/tui/src/headless/exit-policy.ts. ACP returns stopReason: max_turn_requests for the same underlying condition.

Verification I can and cannot claim

Reproduced deterministically on Windows x64 against a local OpenAI-compatible fixture, and pnpm test:byok fails on this at IMAGE_INPUT_TEST (exit 7) on every run before the fix and passes after it.

Not verified: macOS and Linux were not run at all; no real MiniMax backend, Token Plan or BYOK provider was involved, so this is offline fixture evidence, not live-service acceptance; compaction output quality was not assessed, only whether the checkpoint request occurred; ACP was checked at the projection level only, not against a real IDE client; IM channels were checked at the pure-function level only, not against real services.

Screenshots

No response

Before submitting
  • I have searched existing issues.
  • I have included my version and removed sensitive information.

A working patch exists on a fork branch fix/lifecycle-frame-classification (31 files, +633/−113, four new files, no moved or renamed files, generated release/public-source.json and tsconfig.standalone.json regenerated with their scripts). I understand from CONTRIBUTING.md and the issue-template config that external PRs are not accepted; I am not attaching it as a pull request. I can paste the diff, describe any file in detail, or hand the branch to a collaborator if that is useful.

Vorherrschende Sprache
TypeScript
Sterne
2k
Forks
259
Ø Merge
9 Std. 22 Min.
Gemergte PRs (30 T.)
105

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus MiniMax-AI/minimax-code

Alle Issues in MiniMax-AI/minimax-code

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.