Troubleshooting¶
The editor's diagnostics log carries every relevant line. On Windows
it's in %LOCALAPPDATA%/MTE/log/. Look at the newest file after
launching the editor.
"Python plugins disabled"¶
Four flavours; the exact message tells you which one.
PluginHost: MTE_PYTHON is not set; falling back to PATH.¶
Neutral — the host is about to look for Python on PATH. Fine unless
followed by "no Python interpreter found".
PluginHost: MTE_PYTHON path '<value>' does not exist.¶
You set MTE_PYTHON to a path with a directory separator, but the
file at that path is missing. Fix: point at the real python.exe.
PluginHost: MTE_PYTHON='<name>' not found on PATH.¶
You set MTE_PYTHON to a bare name (no separator), but that name isn't
on PATH. Fix: either add the folder to PATH, or use the full path
form above.
PluginHost: no Python interpreter found (…); Python plugins disabled.¶
Neither MTE_PYTHON nor any of the platform-standard names (py.exe,
python.exe, python3.exe on Windows; python3 on macOS/Linux) is on
PATH. Install Python 3.9+ and either add it to PATH or set
MTE_PYTHON.
Check what PATH currently sees, from the same shell you launched the
editor from:
(Get-Command py.exe -ErrorAction SilentlyContinue).Source
(Get-Command python.exe -ErrorAction SilentlyContinue).Source
"python worker script … not found"¶
The editor logs:
The worker host script (mte_python_host.py) isn't next to the exe.
This happens when running an editor build whose Python/ staging
POST_BUILD step was skipped. Rebuild:
Confirm the file exists after the build:
Plugin listed but not loaded¶
Open the Plugins page (Preferences → Plugins). Common causes:
| Symptom | Line in the log | Cause |
|---|---|---|
apiVersion mismatch tag next to the name |
PythonPluginBackend: not loading '…': apiVersion does not match host 1. |
Your plugin.json declares a different apiVersion than the running editor supports. |
| Plugin appears greyed out | PythonPluginBackend: '…' is disabled; listed but not loaded. |
Someone disabled it in the Plugins page. Re-enable and restart. |
| Missing entirely | PythonPluginBackend: skipping '…': module '…/main.py' does not declare a top-level 'def register(...)'. |
The static probe rejected your module. Move register to the top level (column 0). |
| Missing entirely | PythonPluginBackend: skipping '…': module file '…' is missing or unreadable. |
plugin.json.module is "main" but there's no main.py next to it. |
| Missing entirely | PythonPluginBackend: skipping '…': plugin.json missing required field 'id'. |
Add id. |
Command doesn't fire¶
You clicked the menu item / pressed the shortcut but nothing happened.
- Check for
[python:<your.id>] …lines from yourctx.log.info(...). If they're missing, the callback never reached the worker. - Check for
[worker stderr] …lines. Exceptions inside your callback land there. - Confirm the command id in your
add_itemcall matches yourcommand(id=...)verbatim — string comparison is exact.
"worker died" errors¶
The host logs:
The Python subprocess ended. Look above that line for stderr from the
worker — Python prints tracebacks to stderr and the host forwards them
as [worker stderr] …. A crash almost always corresponds to an
uncaught exception in register() or in a callback that recursed into
Python's C API.
Recover by fixing the code and restarting the editor. The host does not auto-restart a crashed worker.
Venv provisioning failed (plugin listed but not loaded)¶
A plugin that declares pyRequires gets a virtual environment
provisioned on its first launch. When that fails, the log carries the
reason:
PluginHost: 'org.example.x' needs a venv (no venv provisioned yet).
PythonRuntime: provisioning venv at '...' (1 requirement(s)); ...
PluginHost: venv provisioning for 'org.example.x' failed: pip install
failed: ... No matching distribution found for no-such-package ...
Common causes: no network on first launch, a misspelled requirement, a
package with no wheel for the user's Python version. Fix the cause and
restart — provisioning retries on every launch until it succeeds
(the venv is only stamped as complete at the end). To force a clean
rebuild, delete <AppLocalData>/PluginVenv/<plugin-id>/. Offline
machines can ship a pre-built venv/ inside the package instead — see
Packaging.
The installer refused my .mteplugin¶
Every rejection comes with a specific dialog message; the common ones:
| Message says… | Fix |
|---|---|
missing the required 'module' field |
Add "module": "main" to plugin.json. |
| no Python module (.py file) | The archive has no .py at all — did you zip the right folder? |
does not contain the declared Python module 'X.py' |
module in plugin.json doesn't match the file name in the archive. |
does not declare a top-level def register(...) |
Same rule as discovery: def register( must start at column 0 of <module>.py. |
| targets API version N | Rebuild against the current apiVersion (see plugin.json). |
| unsafe path / too large / too many files | The archive tripped a safety guard — repack it plainly (no .. entries, < 256 MiB unpacked). |
The package is validated against a scratch copy, so a rejected install never touches an existing plugin.
Nothing is being logged at all¶
Confirm your handler is actually installed. register(ctx) runs
exactly once per plugin per editor launch. If register isn't
defined at module top level, the static probe rejects the plugin
before it's ever loaded (see "Plugin listed but not loaded" above).
Add a startup line to your register:
If you don't see that in the log, the worker isn't executing your
register — check the earlier logs for the reason.
Where to look next¶
- Editor-side log:
%LOCALAPPDATA%/MTE/log/… - Worker stderr: same log, tagged
[worker stderr] - Reference:
ctxAPI, Events,plugin.json - Design notes:
PYTHON_PLUGIN_ARCHITECTURE.md(repo root)