Skip to content

Commands sent while the Editor main thread is blocked wait silently instead of failing fast, although status already reports MainThreadBlocked #3411

Closed

Description

@nyoro-wrl

Environment

  • Windows 11, Unity 6000.6.4f1
  • uloop package 3.21.1, dispatcher 3.13.1, project runner 3.12.2

Problem

When the Editor main thread is blocked, for example by a modal dialog, uloop status correctly reports MainThreadBlocked. But a command sent at that time takes the slot and waits without any message until the main thread resumes. If the block is a dialog nobody answers, the caller waits until the command's own timeout.

Reproduction

  1. Schedule a 60 s main-thread block 5 s from now:
    uloop execute-dynamic-code --code 'var at = UnityEditor.EditorApplication.timeSinceStartup + 5; UnityEditor.EditorApplication.CallbackFunction f = null; f = () => { if (UnityEditor.EditorApplication.timeSinceStartup < at) return; UnityEditor.EditorApplication.update -= f; System.Threading.Thread.Sleep(60000); }; UnityEditor.EditorApplication.update += f; return "scheduled";'
  2. After about 9 s, uloop status returns "State": "MainThreadBlocked" with SecondsSinceLastMainThreadTick around 8.
  3. Run uloop get-hierarchy --max-depth 1. It returns Success: true after 52 s, only once the block ends. Nothing is reported while it waits.

By contrast, a command sent while another command holds the slot during a block fails fast, in about 11 s, with a clear UNITY_SERVER_BUSY message ("waiting for the Editor main thread, which has not responded for 45s ..."). So the blocked state is already detected. It is just not used for the command that holds the slot.

Impact

Agents driving uloop see a command that hangs with no output and can't tell whether to wait, cancel or check the screen. In my project, I work around this with a wrapper that polls uloop status alongside each command. If RunningToolPhase stays WaitingForMainThread, or the main thread stays silent, for about 30 s, the wrapper kills the CLI and tells the agent to look for a dialog.

Expected

If the main thread stays blocked past a threshold while a command waits for it, return an error such as MAIN_THREAD_BLOCKED with the blocked duration and the same guidance status and UNITY_SERVER_BUSY already give (check for a modal dialog, restart only if it persists), instead of waiting until the timeout.

Related

Issue 2320 and the compile stall warning added by its follow-up PRs. That warning covers compile. This issue is about commands in general, which still give no signal while blocked.

Activity

  1. changed the title [-]Commands sent while the Editor main thread is blocked wait silently instead of failing fast, although status already reports MainThreadBlocked[/-] [+]Commands sent while the Editor main thread is blocked wait silently instead of failing fast, although `status` already reports `MainThreadBlocked`[/+] on Oct 28, 2026
  2. hatayama commented on Oct 29, 2026

    @hatayama
    Owner

    Thank you for the report, and especially for the reproduction snippet and the observation that UNITY_SERVER_BUSY already carried the stall; both went straight into the fix.

    Released today in two parts:

    Updating the package to 3.21.3 is enough; the CLI picks up the matching runner on the next command.

    The 30-second threshold matches the CLI's existing stall notice and compile's silent-wait warning; the reasoning and the conditions for changing it are in docs/adr/0020-blocked-main-thread-fails-the-waiting-command.md. If it turns out to be too long or too short in your project, please say so here.

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