Skip to content

compile can strand the session: Unity stalls with isCompiling=true or wedges its main thread, holding single-flight until editor restart #2320

Closed

Description

@hatayama

Summary

During a usability-feedback round (2026-08-21, package revision ef737ee, uloop 3.0.0-beta.32, Unity 6000.3.15f1, macOS), one tester project hit two distinct compile hangs in a single session. Both left the compile request unanswered and single-flight rejecting every other command; the only recovery was restarting the editor. The tester lost the whole verification session (0 hot-reload runs, 0 pause-point runs).

Hang mode 1: build succeeds, pipeline never finishes (isCompiling=true stall)

Timeline (Unity-side vibe log; request compile_*_9bbe9ff5):

  • compile_request_received / compile_request_registered_for_status_polling at T+0.
  • Editor.log shows the Bee build reached *** Tundra build success (only CS0618 warnings for obsolete Rigidbody2D.velocity), then the API Updater ran ([ApiUpdater] ... Files: 1 modified), then nothing — no domain reload, no further compile pipeline output.
  • No compile_finish_callback_received, no watchdog warning (compile_start_timeout / compile_finish_callback_missing / compile_aborted) was ever logged.
  • Status polls kept answering is_compiling: true for the rest of the session (10+ minutes).

Why the watchdog missed it: CompileLifecycleWatchdog treats EditorApplication.isCompiling == true as healthy progress and waits indefinitely; its two timeouts only cover "never started" (5s) and "stopped without callback" (2s grace after isCompiling goes false). A pipeline that stalls while still reporting isCompiling=true is outside both.

Suspected trigger: the API Updater run (obsolete-API rewrite) between build success and assembly reload; possibly a consent/modal path in a backgrounded editor. Not yet reproduced deterministically — a plain no-change compile on the same project succeeded in 7s afterward.

Hang mode 2: editor main thread wedges right after RequestScriptCompilation

Same session after an editor restart (request compile_*_8bfc7d84):

  • compile_request_received / registered logged, one last status poll answered 0.4s later, then the Unity-side IPC went completely silent — no further vibe log entries of any kind until shutdown.
  • Editor.log ends at [ScriptCompilation] Requested script compilation because: Requested through public api — no build ever started.
  • Because the main thread was wedged, neither the watchdog nor the busy gate could respond; even control-play-mode --action Status got no answer.
  • Context: the only change since the previous successful compile was scene mutation (objects placed via execute-dynamic-code); there were no script changes pending.

Root cause unknown. This issue tracks the investigation.

What bounds the damage today

  • The CLI compile poll loop has a 10-minute deadline (compileWaitTimeout), confirmed live: the stranded CLI process stopped polling exactly 10 minutes after its request. So the CLI side is not an infinite hang — but 10 minutes of silent, full single-flight lockout with no interim diagnostics reads as infinite to an agent, and the Unity side stays stuck (mode 1: isCompiling=true forever; mode 2: wedged) until uloop launch -r.

Hardening planned (separate PRs)

  1. Unity-side watchdog escalation for mode 1: when assembly compilation results have been received but compilationFinished does not arrive within a generous no-progress deadline while isCompiling stays true, abort with an indeterminate result naming the possible modal-dialog cause and the uloop launch -r recovery.
  2. CLI-side interim diagnostics during the compile wait: periodic stderr progress notes (elapsed, Unity-reported is_compiling), and an explicit note when status polls stop being answered (editor likely wedged; suggest restart).
  3. Busy rejections name how long the running command has been holding single-flight, so a stuck holder is distinguishable from a slow one.

Evidence (Editor.log copies for both hangs, vibe-log excerpts) is preserved by the reporter; timestamps above are from unity_vibe logs (note: vibe log filenames use the UTC date).

Activity

  1. hatayama commented on Aug 20, 2026

    @hatayama
    OwnerAuthor

    Hardening for both hang modes landed on v3-beta (diagnostics and escape guidance only — no behavior change to compile itself):

    Escalating to any automatic abort remains blocked on additional evidence from this issue: assembly progress that pauses legitimately (large second assembly, post-build processing) is indistinguishable from the stall on the Unity side, and a hard cap would also break the pending-record attach flow for legitimately long compiles.

    Root-cause investigation stays open. The strongest current lead for mode 1 is the API Updater correlation (obsolete Rigidbody2D.velocity usage; Files: 1 modified immediately before the stall).

  2. hatayama commented on Aug 20, 2026

    @hatayama
    OwnerAuthor

    Likely root cause: modal Script Updating Consent dialog

    Reading the Unity Editor source (UnityCsReference) strongly supports a concrete mechanism for the Round 8 hangs:

    • When the ScriptUpdater finds source files using updatable obsolete APIs (Round 8 trigger: Rigidbody2D.velocity), UnityScriptUpdaterConsentAPI.AskFor runs. In an interactively launched Editor it shows a modal dialog via EditorUtility.DisplayDialogComplex("Script Updating Consent", ...) (Editor/Mono/Scripting/ScriptCompilation/BeeDriver/UnityScriptUpdaterConsentAPI.cs).
    • The dialog is skipped only when command-line flags indicate consent/decline, or during project creation. uloop launch starts the Editor interactively with neither, so none apply.
    • In an agent-driven workflow nobody can click the dialog. The main thread sits in the modal's nested event loop, so main-thread-bound work — compile pipeline callbacks and IPC dispatch — stops entirely. From the CLI this looks exactly like the observed symptom: a compile that never completes, with assembly-finished callbacks ceasing partway.

    This matches all Round 8 observations: correlation with obsolete-API usage and API Updater activity right before the stall, indefinite hang, and zero recurrence in Round 9 where no tester touched an obsolete API.

    Not yet verified directly (no screenshot/Editor.log of the dialog survives from Round 8; logs rotated). Cheap repro: add an obsolete-API script to a scratch project, run uloop compile, and capture the screen with the OS tool when it stalls (uloop screenshot would block on the same modal).

    Candidate fixes

    1. Pass -accept-apiupdate from uloop launch — command-line consent skips the dialog and the updater rewrites files silently; the CLI should disclose the rewrite in the compile response.
    2. Decline updating via the command line instead, so obsolete APIs surface as compiler diagnostics the agent fixes itself.
    3. Minimum: detect the pending-consent state and name the blocking dialog in the stall warning added by feat: log assembly-progress stalls while Unity keeps reporting compiling #2321.

    Direction (1 vs 2) needs a product decision; deferring the fix proposal until the current Round 9 fix round lands.

  3. hatayama commented on Aug 21, 2026

    @hatayama
    OwnerAuthor

    Resolved by the two PRs planned for this issue:

    The separate 'API Update Required' dialog is intentionally not suppressed; it is covered by the improved stall warning only.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions