Skip to content

All tools stuck on "busy: compiling" when a project defers domain reload via EditorApplication.LockReloadAssemblies #1276

Description

@kingblade

What happened?

Projects that implement a "manual compile" workflow keep EditorApplication.LockReloadAssemblies() held so that script changes compile but the domain reload is deferred until the user explicitly triggers it (a common editor-productivity pattern; several Asset Store tools do the same).

In that state, EditorApplication.isCompiling stays true from the moment a compile finishes until the deferred reload actually runs — which can be minutes or hours later. Because EditorStateCache.GetActualIsCompiling() trusts the raw flag outside Play mode, the readiness snapshot (editor_state) reports compilation.is_compiling: true / activityPhase: "compiling" indefinitely, so the server-side readiness gate rejects every tool call before it reaches Unity:

{"success":false,"message":"compiling","error":"busy","data":{"reason":"compiling","retry_after_ms":500},"hint":"retry"}

The agent is fully locked out even though no compilation is running and the editor is idle.
This is made worse by manage_script/create_script calling CompilationPipeline.RequestScriptCompilation() themselves: the agent's own script edit permanently bricks every subsequent call until the user manually reloads.

Root cause

This is the same false positive already worked around for Play mode in #549 ("Recompile After Finished Playing" keeps isCompiling true for the whole play session):
isCompiling means "compile pending OR reload deferred", not "compilation running". The existing workaround only applies while EditorApplication.isPlaying.

Proposed fix

Extend the #549 workaround to all modes — trust the event-tracked pipeline state whenever the raw flag is set, in MCPForUnity/Editor/Services/EditorStateCache.cs:

internal static bool GetActualIsCompiling()
{
    // If EditorApplication.isCompiling is false, Unity is definitely not compiling
    if (!EditorApplication.isCompiling)
    {
        return false;
    }

    // EditorApplication.isCompiling also stays true while a finished compile's domain
    // reload is deferred — during a Play session under "Recompile After Finished
    // Playing" (#549) or whenever EditorApplication.LockReloadAssemblies() is held
    // (manual-compile workflows). In both cases no compilation is running, so trust
    // the event-tracked pipeline state instead of the raw flag.
    return _pipelineCompilationRunning;
}

StdioBridgeHost.IsCompiling() has the same issue for the bridge-startup gate and could delegate to EditorStateCache.GetActualIsCompiling().

Reproduction steps

  1. In any editor script, call EditorApplication.LockReloadAssemblies() (e.g. from
    [InitializeOnLoad]).
  2. Edit any .cs file and let it import/compile (or call manage_script).
  3. After compilation finishes, every MCP tool call returns the busy/compiling error above, despite the editor being idle.

Unity version

6000.0.58f2

MCP for Unity package version

10.1.0

Python server version

No response

MCP client

Claude Code

Transport

HTTP (default)

OS

Windows

Relevant logs / console output


Checks

  • I searched existing issues and did not find a duplicate
  • I included logs / steps to reproduce

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions