CoplayDev/unity-mcp · critical · EditorNotFound

No Unity editor binary found. Searched:\n {searched}

Error message

No Unity editor binary found. Searched:\n  {searched}

What it means

Raised by discover_editor in tools/local_harness.py after probing every candidate editor path (explicit --editor, Hub installs, secondary install path, and same-major.minor nearest-patch fallback) and finding none both existing and executable. The exception carries the full list of absolute paths searched so the harness can print remediation guidance (exit code 5).

Source

Thrown at tools/local_harness.py:406

            entries = _listdir(root)
        except OSError:
            continue
        for name in entries:
            pv = parse_version(name)
            if (pv[0], pv[1]) != (target[0], target[1]):
                continue
            binary = str(Path(root) / name / relpath)
            searched.append(binary)
            if not (_exists(binary) and _is_exec(binary)):
                continue
            key = (pv[2], pv[3])
            if best is None or key > best[0]:
                best = (key, binary, name)

    if best is not None:
        return EditorSpec(binary=best[1], version=best[2])

    raise EditorNotFound(searched=searched)


# ===========================================================================
# Pure helpers: status-file discovery
# ===========================================================================
def newest_status_file(status_dir: str | Path,
                       glob_fn: Callable[[str], list[str]] | None = None,
                       mtime_fn: Callable[[str], float] | None = None) -> str | None:
    """Return the path to the newest unity-mcp-status-*.json under status_dir, or None."""
    pattern = str(Path(status_dir) / "unity-mcp-status-*.json")
    g = glob_fn or glob.glob
    files = list(g(pattern))
    if not files:
        return None
    m = mtime_fn or (lambda p: os.path.getmtime(p))
    try:
        return max(files, key=m)
    except OSError:

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Install the requested Unity version via Unity Hub and ensure it is fully downloaded (not just the module manifest).
  2. Pass --editor /path/to/Unity to point the harness at a non-Hub install explicitly.
  3. chmod +x the editor binary if it exists but is not executable; verify the Hub install path matches hub_roots for your platform.

Example fix

# before
python tools/local_harness.py  # searched many paths, none executable
# after
chmod +x /Applications/Unity/Hub/Editor/2022.3.0f1/Unity.app/Contents/MacOS/Unity
python tools/local_harness.py --editor /Applications/Unity/Hub/Editor/2022.3.0f1/Unity.app/Contents/MacOS/Unity
Defensive patterns

Strategy: validation

Validate before calling

spec = discover_editor(version, explicit_editor=args.editor)
# guard before calling:
if not args.editor and not hub_has_version(version):
    raise SystemExit('install Unity {version} via Hub or pass --editor')

Type guard

def editor_executable(path: str) -> bool:
    return os.path.exists(path) and os.access(path, os.X_OK)

Try / catch

from tools.local_harness import EditorNotFound
try:
    spec = discover_editor(version)
except EditorNotFound as e:
    print('Searched:\n  ' + '\n  '.join(e.searched)); sys.exit(5)

Prevention

When it happens

Trigger: discover_editor iterates candidate_editor_paths and the nearest-patch Hub directories; none pass the _exists and _is_exec checks. EditorNotFound(searched=[...]) is raised at local_harness.py:406.

Common situations: Unity Hub not installed or installed elsewhere; the requested version's editor binary lacks execute permission (e.g., on a fresh Linux untar); the Hub install is an editor-data folder without the Unity executable; wrong platform relpath.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/f118ce4dc0ec7edb. Report an issue: GitHub.