Debugging and panic recovery in SuperCollider
Learning objectives
- learner can diagnose the nine L1 silent-failure patterns in SuperCollider: unbooted server, stale SynthDef, rate mismatch, Pseq without inf, missing quant, consumable stream misuse, degree without scale, Ndef silent re-eval, and absence of a global limiter
- learner can read the post window as the single error surface — distinguish language errors, runtime errors, and server messages — and act on each while the server keeps playing the last good nodes
- learner can trace any performance failure to its error class using the error taxonomy (server-state, rate, SynthDef, pattern, JITLib, gain runaway) and select the correct fix without stopping the set
- learner can execute an autonomous two-step panic recovery — s.freeAll then a dependency-free inline graph — and knows when to escalate to s.reboot, while also accepting that SuperCollider is audio-only in this rig and cannot drive its AV bridge
Capstone — one whole task that evidences the objectives
Run a five-minute live SuperCollider set from a file deliberately seeded with one fault per error class, and recover from each in real time using only the post window plus sc.avgCPU / sc.nodeCount — never a search engine. The seeds: (1) the server not yet booted (silence + 'Server not running'); (2) a SynthDef edited but never re-added, so the old cached graph plays; (3) a hallucinated / mis-cased UGen name that posts 'not understood'; (4) a control-rate .kr UGen fed where audio-rate .ar is required; (5) a Pseq missing 'inf' that silences a voice after one pass, plus a \\degree key with no \\scale playing wrong pitches, plus a pattern started without .play(quant:) that drifts out of phase; (6) an Ndef re-evaluated with a syntax error that silently keeps the old JITLib graph running (and a note on why ProxySpace needs push); (7) a percussive synth without doneAction:2 that leaks nodes until CPU crackles, alongside a gain/feedback runaway that throws no error while volume climbs — there is no global limiter to catch it. For each fault, name its error class, state what the symptom sounds like (silence, wrong pitch, drift, noise, or clipping) versus what the post window shows, and apply the fix without stopping the other voices. When state collapses, execute the autonomous two-step panic recovery — s.freeAll then a single inline {}.play graph needing no SynthDef, sample, pattern, or scale — and say when s.reboot replaces step one. Finally, in a written note, explain why you cannot .asStream.next a pattern twice to recover it, and why this SC set drives no visuals in this rig: its analysis UGens are not wired to the AV bridge, so SC is audio-only and source-only here.
Prerequisite modules
This module is built around a single performance reality: when SuperCollider breaks live, nothing tells you. There is no modal dialog, no syntax highlight, no beep. The server keeps playing the last good nodes while the post window fills with errors no audience will ever read. The skill this module develops is learning to treat the post window as a diagnostic instrument and to act inside it in real time, without stopping the set.
The twenty-three atoms fall into two interlocking layers. The first layer (L1 gotchas) covers the mechanical invariants that break every new SuperCollider user and every experienced one working in a new environment. The server must be booted before any sound is possible; the language gives no error if it is not, it simply goes silent. A SynthDef edited but not re-evaluated leaves the server running the old cached version with no indication. A control-rate .kr UGen fed into an audio-rate slot errors or aliases in ways that sound like synthesis bugs rather than type errors. Pseq without inf plays once then stops silently, leaving a voice that appears present but produces nothing. A \degree key without an accompanying \scale defaults to C major and plays wrong pitches with no error. Patterns started without .play(quant:) drift out of phase with the clock. Calling .asStream.next on a pattern consumes and discards the stream irreversibly. Re-evaluating an Ndef with a syntax error keeps the old graph running silently. And with no global output limiter, summed voices or feedback runaway can clip or blow up without any warning from the server. None of these produce obvious errors — they produce silence, wrong notes, or noise. The first drills are recognition-and-fix pairs timed under two minutes each: given the symptom, name the error class and write the fix.
The second layer (L5 debug) extends those nine patterns with the diagnostic reasoning needed to apply them under performance pressure. The post window is the only error surface: language errors (syntax, parse) print immediately on evaluate; runtime errors print ‘ERROR:’ with a call stack; server failures print ‘FAILURE’, ‘node not found’, or late message warnings. Crucially, all three share one window and a booted server ignores language errors entirely — the old graph keeps playing. A JITLib Ndef re-evaluation that fails silently is the canonical trap: nothing changes audibly, no error sounds, only the post window tells you the edit did not take. The L5 diagnostic loop is: evaluate, watch the post window within two seconds, interpret what you see against the six error classes (server-state, rate, SynthDef, pattern, JITLib, gain runaway), and select the fix without touching anything else.
Node leak via missing doneAction: 2 is the subtlest of the L5 patterns. Percussive synths that do not free their server node when the envelope completes accumulate silently; voice count climbs with no error until CPU overload causes crackle or dropouts that sound like an audio driver problem. The fix is architectural — every amplitude EnvGen needs doneAction: 2 — not a per-incident patch. The gain runaway pattern is similar: SuperCollider throws no error as volume climbs toward clipping or DC offset blowup; only the symptom (rising volume, distortion, eventual silence) signals the cause. Both patterns train the performer to monitor sc.avgCPU and sc.peakCPU as secondary diagnostic channels alongside the post window.
The JITLib/ProxySpace distinction enters at L5 because it changes the recovery procedure. Ndef replaces a running graph on successful re-evaluation, so a failed re-eval leaves the previous graph running, not silence. ProxySpace requires push before tilde-name access; tilde-names in the wrong scope silently route to environment variables, not the proxy. Understanding which live-coding abstraction is in use determines whether a broken edit produced silence, the previous state, or a spurious new voice.
The AV bridge constraint is an L1 fact with L5 implications. SuperCollider’s analysis UGens — FFT, Amplitude, Onsets, SendReply — are not wired to this rig’s AV bridge; the bridge is driven exclusively by Strudel’s four FFT bins. Any attempt to author SC-to-visual reactivity as if SC feeds Hydra will produce no error and no visual response. The correct mental model is: SC is audio-only and source-only in this rig. Recognising hallucinated UGen names — capitalization matters, a misspelled class posts ‘not understood’ rather than producing silence — is the remaining L1 gotcha in this layer, since AI-generated SC code frequently produces syntactically valid but nonexistent UGen names.
The autonomous panic recovery is the capstone’s core deliverable. When performance state collapses — leaked nodes, runaway feedback, broken JITLib, dead SynthDef — the recovery is exactly two steps: (1) s.freeAll to clear all nodes and stop any runaway immediately, then (2) a single inline {}.play graph requiring no SynthDef, no samples or buffers, no pattern, and no scale. The canonical panic graph is { RLPF.ar(Saw.ar(110), 800, 0.3) * SinOsc.kr(0.2).range(0.05, 0.2) }.play — each dependency that a real voice has is absent, so it survives every error class simultaneously. When the server itself is unresponsive, s.reboot replaces step 1. The annotation requirement in the capstone forces explicit reasoning: the learner names the error class for each fixed fault and labels each constraint in the panic graph. This documentation becomes a personal recovery protocol for the next set.
Atoms in this module
Required — these gate the capstone
Supporting — enrichment, not gating
Part of curricula
- Live Coder — zero to performing live-coded music — Performing Live required
- Synthesist / Sound Designer — deep DSP to a performed live synth rig — Performing the live synth rig recommended