skills/commontoolsinc/labs/pattern-debug

pattern-debug

SKILL.md

Debug Pattern

Use Skill("ct") for ct CLI documentation if debugging deployment or piece issues.

Read First

  • docs/development/debugging/workflow.md - 5-step debugging process
  • docs/development/debugging/README.md - Error reference matrix

Process

  1. Check TypeScript errors:

    deno task ct check pattern.tsx --no-run
    
  2. Match error to documentation:

    • Read the error message carefully
    • Check docs/development/debugging/README.md for matching errors
  3. 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
  4. Simplify to minimal reproduction:

    • Comment out code until error disappears
    • Add back piece by piece to find root cause
  5. 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) inside derive() 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
Weekly Installs
44
GitHub Stars
30
First Seen
Jan 21, 2026
Installed on
opencode44
gemini-cli44
cursor44
antigravity43
codebuddy43
github-copilot43