Debugging¶
A Remote Script runs inside Live's embedded Python interpreter, so you cannot just run it and read a traceback in a terminal. This page covers the handful of techniques that make scripting bearable: seeing output, surviving errors, and a checklist for the classic failures.
Log.txt, your console¶
Live writes a log file you can tail while it runs. Anything your script logs (and every Python exception it raises) lands here.
Locations:
- macOS,
~/Library/Preferences/Ableton/Live <version>/Log.txt - Windows,
\Users\<you>\AppData\Roaming\Ableton\Live <version>\Preferences\Log.txt
Watch it live while you work:
To write to it from your script, use the ControlSurface logging helper or Python's logging:
self.log_message("hello from my script") # simplest, always available
# or
import logging
logging.getLogger(__name__).info("value = %s", value)
self.log_message prefixes the line with your script name, which makes it easy to grep:
show_message, talk to the user¶
To surface something in Live's status bar (bottom-left), not just the log:
Good for confirming a mode switch or a non-fatal condition the performer should see.
Survive your own errors¶
An unhandled exception in a callback can wedge the script (LEDs freeze, input stops). During development, wrap risky handlers so one bad event doesn't take everything down, and log the traceback:
import traceback
def _on_value(self, value):
try:
self._do_something(value)
except Exception:
self.log_message(traceback.format_exc())
Remove or tighten these once the logic is stable, silently swallowing exceptions in production hides real bugs.
The reload loop¶
There is no hot-reload. The cycle is:
- Edit the script.
- In Live, deselect your control surface in Preferences → Link/Tempo/MIDI, then select it
again. (Re-selecting re-runs
create_instance.) Some setups require quitting and relaunching Live to clear cached bytecode. - Watch
Log.txtfor the load and any traceback.
Deleting stale __pycache__ folders next to your .py files avoids running an old compiled
version after an edit.
Checklist, "my script doesn't show up"¶
Work down this list; it covers the overwhelming majority of cases.
- The folder is in the right place (Live's
MIDI Remote Scriptsfolder, or the user remote scripts folder for your OS) and contains an__init__.py. __init__.pydefinescreate_instance(c_instance)and returns yourControlSurface.- The folder name has no spaces or odd characters.
- There is no import error at load time, check
Log.txt; an exception during import makes the script vanish from the dropdown. - You re-selected the surface (or relaunched Live) after editing.
Checklist, "it loads but nothing works"¶
- Did you build everything inside the component guard? Controls created outside it may not be registered. See the ControlSurface lifecycle.
- Is the element's MIDI identity (type, channel, number) actually what the hardware sends? Send a
message and confirm in
Log.txtor with a MIDI monitor. - Is the control bound in the currently active layer/mode? A correct component with the wrong layer does nothing.
- For feedback: did you register a listener on the LOM property, and are you sending the value back out through the element?
Checklist, "LEDs stay lit after I switch it off"¶
- Your
disconnect()must turn controls off and remove listeners. Leaking listeners is the most common cause of stuck LEDs and of Live getting slower over a session. The lifecycle guide covers clean teardown.