Debug Pattern
Use the ct skill, or read skills/ct/SKILL.md, if debugging deployment or piece issues.
Read First
docs/development/debugging/workflow.md- 5-step debugging processdocs/development/debugging/README.md- Error reference matrix
Process
- Check TypeScript errors:
deno task ct check pattern.tsx --no-run - Match error to documentation:
- Read the error message carefully - Check docs/development/debugging/README.md for matching errors
- Check gotchas:
- docs/development/debugging/gotchas/handler-inside-pattern.md - docs/development/debugging/gotchas/filter-map-find-not-a-function.md - docs/development/debugging/gotchas/onclick-inside-computed.md
- Simplify to minimal reproduction:
- Comment out code until error disappears - Add back piece by piece to find root cause
- Fix and verify:
- Apply fix - Run tests to confirm
Common Issues
Handler defined inside pattern body:
- Move handler() to module scope
- Only bind it inside pattern:
onClick={myHandler({state})}
Type errors with Writable/Default:
- Check if field needs write access → use Writable<>
- Check if field could be undefined → use Default<T, value>
Action not triggering:
- Ensure Output type includes action as Stream
- Use.send() not.get() to trigger
computed() wrapping JSX — conditional rendering broken:
- Inside
computed()body, ternaries are plain JS (Writable objects always truthy) - Cell bindings (
$value,$checked) insidederive()may get positionally mis-resolved - Fix: use bare JSX ternaries, hoist
computed()for data only - See
docs/common/concepts/computed/computed.md
Runtime Debugging (browser)
When the pattern compiles but behaves wrong at runtime, use the browser console utilities. Full reference: docs/development/debugging/console-commands.md.
With agent-browser (for automated testing):
# Read piece cell values
agent-browser eval "(async () => {
const v = await commontools.readCell();
return JSON.stringify(v).slice(0, 500);
})()"
# Inspect VDOM tree
agent-browser eval "(async () => {
await commontools.vdom.dump();
return 'dumped';
})()"
# Detect non-idempotent computations (UI churning)
agent-browser eval "(async () => {
const r = await commontools.detectNonIdempotent(5000);
return JSON.stringify({ nonIdempotent: r.nonIdempotent.length, cycles: r.cycles.length });
})()"
# Check for action schema mismatches (handlers doing nothing)
agent-browser eval "JSON.stringify(commontools.getLoggerFlagsBreakdown())"In browser console (for interactive debugging):
// Read cell values
await commontools.readCell();
await commontools.readArgumentCell({ path: ["items"] });
// Watch values change during interaction
const cancel = commontools.subscribeToCell();
// ... interact ... then cancel()
// VDOM tree
await commontools.vdom.dump();
commontools.vdom.stats();
// Logger counts and timing
commontools.getLoggerCountsBreakdown();
commontools.getTimingStatsBreakdown();
// Non-idempotent detection
await commontools.detectNonIdempotent();Done When
- Root cause identified
- Error fixed
- Tests pass again