Repository navigation
[Bug]: Desktop utility bootstrap blocks on thread-goal and queue recovery, then times out after 600000ms #512
Description
Product or interface
Desktop app
Version
3.1.3-inside.122
Platform
macOS
OS version and architecture
macOS 27.0.1 (26A434), arm64
Issue area
Startup / install / update
Desktop log upload ID
453999839174989
Uploaded from Settings on 2026-10-20. Raw session files are not pasted here.
Steps to reproduce
- Use MiniMax Code Desktop 3.1.3-inside.122 on macOS arm64 with an existing local runtime profile.
- Leave one thread goal with
status=activeandkickoff_state=consumed, and leave a small number of queue rows withstatus=queued(one of themsource=thread-goalfor that goal, plus a few ordinary queued turns on other sessions). - Quit and relaunch the desktop app.
- Watch
~/Library/Logs/MiniMax/main-*.logforUtilityRuntimebootstrap progress.
Expected and actual behavior
Expected: the utility process reaches sqlite-ready and reports ready within a few seconds. Recovering an active thread goal or draining queued turns must not block process readiness. A cloud request that does not return should time out and be retried after the runtime is ready.
Actual: bootstrap reaches modules-loaded in about 1.5s, logs sandbox.lifecycle_changed with runtime_state=disabled, and then never logs External channel subsystem bound to the v1 host facade or stage=sqlite-ready. The utility process stays alive at about 0% CPU with an established TCP connection to agent.minimax.cn:443. After exactly 600000ms the supervisor logs:
[UtilityRuntime] bootstrap stalled at stage modules-loaded for 600000ms (1/3); killing utility process
The user-visible error is utility bootstrap timed out after 600000ms. Each relaunch repeats the same stall. The 600000ms value matches BOOTSTRAP_STALL_TIMEOUT_MS: the watchdog measures silence since the last bootstrap stage, and nothing between modules-loaded and sqlite-ready reports progress.
Workaround that unblocked this profile: pause that active thread goal (do not delete it) and remove the queued/claimed queue rows, then relaunch. The next boot logged sqlite-ready at 1790ms and ready at total=2298ms. No session content was required for the workaround; only the durable goal status and queue-item status mattered.
Redacted error summary
[UtilityRuntime] bootstrap progress stage=node-entry elapsed=170ms
[UtilityRuntime] bootstrap progress stage=modules-common-done elapsed=1182ms
[UtilityRuntime] bootstrap progress stage=modules-runtime-v2-done elapsed=1515ms
[UtilityRuntime] bootstrap progress stage=modules-loaded elapsed=1515ms
... sandbox.lifecycle_changed runtime_state=disabled ...
# no further bootstrap stage for 600000ms
[UtilityRuntime] bootstrap stalled at stage modules-loaded for 600000ms (1/3); killing utility process
utility bootstrap timed out after 600000ms
# after pausing the active goal and clearing queued rows:
[UtilityRuntime] bootstrap progress stage=sqlite-ready elapsed=1790ms since_previous=293ms
[UtilityRuntime] ready total=2298ms preparation=479ms bootstrap=1819ms
Notes for triage
The hang is on the desktop local-runtime utility, after modules are loaded and after the sandbox service has published runtime_state=disabled, and before bindExternalChannelSubsystem. That window includes services.ready(), and conversation.bind() awaits recoverThreadGoalKickoffs() while startup execution is enabled. listRecoverableActiveGoals() selects rows with kickoff_state=consumed and status=active. Separately, authenticated startup recovery dispatches every session returned by listPendingSessionIds() (status queued or claimed) and awaits that dispatch.
Please treat the causal link as: removing those durable rows made an otherwise identical boot finish in about 2s, and during the hang the only useful external activity was a TCP connection to agent.minimax.cn that never completed. A JavaScript stack at the time showed an idle event loop, so the blocked wait is likely a native request without a bootstrap-scoped deadline.
Suggested change:
- Do not await thread-goal continuation or queue dispatch before reporting
sqlite-ready. Run that recovery after ready, detached, the same way owner channel startup already is. - Give any cloud call that can still overlap bootstrap a short timeout, and fail open.
- Emit a bootstrap progress stage for the recovery step, so a stall names "goal recovery" or "queue dispatch" instead of only "modules-loaded".
Activity