home/ modules/ debugging-and-panic-recovery-in-supercollider

Debugging and panic recovery in SuperCollider

  • 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

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.

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

SuperCollider produces no sound until the audio server is explicitly booted with s.boot
Fact L1 Foundations F
s.freeAll (Cmd-.) frees every running node but leaves the server booted and SynthDefs loaded
Fact L1 Foundations F
Editing a SynthDef without re-running .add spawns the old definition on the server silently
Misconception L1 Foundations F
Feeding a control-rate .kr signal where audio-rate .ar is required errors or aliases audibly
Concept L1 Foundations FB
A SuperCollider pattern's degree defaults to C major unless a scale, root, and octave are given
Misconception L1 Foundations FA
SuperCollider patterns started without .play(quant:) begin immediately and drift out of phase
Procedure L1 Foundations F
Pseq without an explicit repeats argument plays the list once then stops, silencing the voice
Misconception L1 Foundations F
Calling .asStream.next consumes a SuperCollider pattern's stream, which cannot be rewound
Concept L1 Foundations F
Re-evaluating an Ndef with a syntax error keeps the old graph running with no audible indication
Misconception L1 Foundations F
SuperCollider has no global output limiter, so summed voices and feedback can clip or blow up
Principle L1 Foundations FB
SuperCollider audio-analysis UGens are not wired to this rig's AV bridge and cannot drive its visuals
Fact L1 Foundations FJ
SuperCollider class names are capitalized and methods lowercase; misspelling a UGen name fails outright
Misconception L1 Foundations F
SuperCollider errors surface in the post window while the booted server keeps playing the last good nodes
Concept L5 Voice F
Playing a SuperCollider synth before s.boot produces silence and a 'Server not running' post message
Misconception L5 Voice F
Mixing audio-rate and control-rate UGens in SuperCollider fails the SynthDef build with a 'not audio rate' post message
Misconception L5 Voice F
A SuperCollider SynthDef must be re-added after every edit or Synth plays the old cached graph
Misconception L5 Voice F
A SuperCollider synth without doneAction:2 leaks nodes silently until CPU overload crackles
Misconception L5 Voice F
SuperCollider gain and feedback runaway throws no error — only rising volume, clipping, or DC blowup signals it
Misconception L5 Voice F
SuperCollider JITLib's Ndef replaces a running graph on re-eval while ProxySpace requires push before tilde-name access
Concept L5 Voice F
SuperCollider Pseq without 'inf' repeats plays once then stops silently
Misconception L5 Voice F
A SuperCollider \degree pattern with no \scale defaults to C major and plays wrong pitches without error
Misconception L5 Voice F
A SuperCollider UGen name that is miscased or not installed posts 'not understood' rather than playing
Misconception L5 Voice F
A SuperCollider autonomous panic recovery is s.freeAll followed by a single inline graph needing no SynthDef, sample, pattern, or scale
Procedure L5 Voice F

Supporting — enrichment, not gating

SuperCollider is two separate processes: a language client and a sound server
Concept L1 Foundations FBN
The Post window is SuperCollider's primary feedback channel for results, warnings, and errors
Concept L1 Foundations FN
SynthDef names and stores a reusable synth recipe in the server; Synth instantiates it with specific argument values
Procedure L2 First instrument FB
doneAction: 2 tells a UGen to free its enclosing synth node when it finishes, preventing silent zombie synths
Concept L2 First instrument FBN
ServerBoot and ServerTree callbacks ensure SynthDefs and resources load in the correct order after server boot
Concept L3 Craft F
UGens run at audio rate (.ar) or control rate (.kr), trading CPU for update resolution; only .ar signals reach the speakers
Concept L1 Foundations FB