debug-opensrc
Debug with OpenSrc
Overview
When bugs trace into third-party code, guessing from type definitions wastes time. Reading the actual source reveals the root cause.
Core principle: Read the REAL source code, not type definitions or README. The answer is in the implementation.
Violating this process by guessing from types is violating the spirit of debugging.
The Iron Law
NO GUESSING ABOUT THIRD-PARTY BEHAVIOR — READ THE SOURCE
If the error traces into a dependency, you MUST read its source before proposing fixes.
When to Use
Use when:
- Error stack trace goes into
node_modules/or external package - Package behavior doesn't match documentation
- Type definitions suggest one thing, runtime does another
- Need to understand internal data flow of a dependency
- Config options have undocumented side effects
- Two packages interact unexpectedly (e.g., better-auth + convex)
- "This should work according to the docs" but it doesn't
Especially use when:
- Under time pressure (guessing wastes MORE time)
- You've already tried multiple workarounds
- Issue involves package integration (auth + DB, ORM + framework)
Don't use when:
- Issue is clearly in your own code with clear error message
- Package documentation fully explains the behavior
- Simple config typo (just fix it)
The Four Phases
You MUST complete each phase before proceeding to the next.
Phase 1: Source Retrieval
BEFORE hypothesizing about package behavior:
-
Identify the Package
- Which package is the error in?
- What version are you using? (check
package.jsonor lockfile) - Is it an npm package, PyPI, or GitHub repo?
-
Fetch Source Code
# Single npm package opensrc path zod opensrc path better-auth opensrc path convex # With specific version opensrc path zod@3.22.0 # GitHub repo opensrc path vercel-labs/agent-browser opensrc path lightpanda-io/browser # Python package opensrc path pypi:requests # Multiple packages at once opensrc path better-auth better-auth-convex convex # Search inside fetched source rg "createAuth" $(opensrc path better-auth-convex) rg "adapterConfig" $(opensrc path better-auth-convex)/src/adapter.ts cat $(opensrc path better-auth)/src/plugins/ -
Verify Source Retrieved
opensrc listto confirm cached- If fetch fails, try with
--verbose - Large repos (like convex-backend) may take longer — be patient
Phase 2: Source Investigation
Read the actual implementation, not the types:
-
Locate the Relevant Code
# Find the file that handles the failing behavior rg "functionName\|className\|error message" $(opensrc path <package>) # Read the specific file cat $(opensrc path <package>)/src/module/file.ts # Find all exports rg "export" $(opensrc path <package>)/src/index.ts -
Read Implementation Completely
- Don't skim — read every line of the relevant function
- Check helper functions it calls
- Look at default parameter values
- Check conditional branches (they often hide the bug)
-
Understand Data Flow
# Trace how input transforms through the package rg "input\|parse\|validate\|transform" $(opensrc path <package>)/src/ # Find where configuration is consumed rg "options\|config\|settings" $(opensrc path <package>)/src/ -
Check Package Integration Points
# When debugging inter-package issues, fetch both opensrc path better-auth better-auth-convex # Trace the adapter boundary rg "adapter\|plugin\|middleware\|hook" $(opensrc path <package-1>)/src/ rg "adapter\|plugin\|middleware\|hook" $(opensrc path <package-2>)/src/
Phase 3: Pattern Analysis with Source
Compare what you found vs what you expected:
-
Document the Gap
- What does the source ACTUALLY do?
- What did you ASSUME it does?
- Where exactly does the mismatch occur?
-
Find Working Examples in Source
# Look at tests for correct usage find $(opensrc path <package>) -name "*.test.*" -o -name "*.spec.*" # Look at examples directory ls $(opensrc path <package>)/examples/ 2>/dev/null -
Identify the Root Cause
- Is it a config issue? (missing/incorrect option)
- Is it a version mismatch? (API changed between versions)
- Is it an undocumented requirement? (side-effect, initialization order)
- Is it a bug in the package itself? (wrong logic, missing edge case)
- Is it an integration mismatch? (packages expect different data shapes)
-
Check for Known Patterns
# Common pitfalls in source rg "TODO\|FIXME\|HACK\|XXX" $(opensrc path <package>)/src/ # Check how errors are thrown rg "throw\|Error\|reject" $(opensrc path <package>)/src/
Phase 4: Informed Fix
Now that you understand the real behavior, fix it:
-
Create Failing Test
- Reproduce the issue with minimal code
- One test case that proves the bug
-
Implement Fix
- If config issue: correct the configuration
- If integration mismatch: add adapter/transform layer
- If package bug: file issue, implement workaround with source-level understanding
- NEVER monkey-patch without understanding WHY
-
Verify Against Source
# After fix, verify behavior matches what source expects rg "the-function-you-fixed\|the-config-you-changed" $(opensrc path <package>) -
If Fix Doesn't Work
- STOP. Re-read the source more carefully.
- You likely missed a code path or side-effect.
- Count: How many fixes have you tried?
- If ≥ 3: The integration pattern may be wrong. Question the approach.
Red Flags - STOP and Read the Source
If you catch yourself:
- "This package probably works like..."
- "According to the types, it should..."
- "The README says to use it this way..."
- "Let me just try a different config..."
- "Maybe if I pass this extra option..."
- Proposing workarounds without reading implementation
- Reading type definitions instead of source code
- "The docs say X but it's doing Y" — READ THE SOURCE, it reveals the truth
ALL of these mean: STOP. Fetch and read the source code.
Common Rationalizations
| Excuse | Reality |
|---|---|
| "Types tell me enough" | Types don't show runtime logic, side-effects, or default values. |
| "README covers this" | README is marketing, source is truth. 30% of READMEs have gaps. |
| "I'll just try different configs" | Without source understanding, you're guessing. 5 min reading > 30 min guessing. |
| "Package is too complex to read" | You only need to read the RELEVANT function, not the entire codebase. |
| "Source won't help, it's a config issue" | Config issues ARE source issues — defaults live in source, not docs. |
| "I already know how this works" | If it's broken, your mental model is wrong. Source corrects it. |
| "I'll check Stack Overflow" | SO answers may be outdated or wrong. Source is always current. |
| "Reading source takes too long" | 5 minutes reading source vs 2 hours guessing. Source is faster. |
Quick Reference
| Phase | Key Command | Success Criteria |
|---|---|---|
| 1. Retrieve | opensrc path <pkg> |
Source cached locally |
| 2. Investigate | rg "pattern" $(opensrc path <pkg>) |
Found relevant implementation |
| 3. Analyze | Compare source vs expectation | Identified root cause |
| 4. Fix | Implement based on source understanding | Bug resolved, tests pass |
Supported Registries
| Registry | Syntax | Example |
|---|---|---|
| npm | default or npm: |
opensrc path zod |
| PyPI | pypi: pip: python: |
opensrc path pypi:requests |
| crates.io | crates: cargo: rust: |
opensrc path crates:serde |
| GitHub | owner/repo |
opensrc path vercel-labs/agent-browser |
| GitLab | gitlab: |
opensrc path gitlab:owner/repo |
Cache Management
opensrc list # Show all cached sources
opensrc remove <pkg> # Remove specific package
opensrc clean # Remove everything
opensrc clean --repos # Only GitHub/GitLab repos
opensrc clean --npm # Only npm packages
opensrc clean --pypi # Only PyPI packages
Cache location: ~/.opensrc/ (override with OPENSRC_HOME env var)
Real-World Impact
- better-auth + convex integration:
adapterConfigmaps_id↔id, converts dates to numbers — info NOT in docs, only inadapter.tssource - Zod parsing issues: Source reveals
transformruns afterrefine, explaining validation order bugs - Convex query behavior: Source shows cursor-based pagination internals, explaining "missing results" bugs
5 minutes reading source > 2 hours guessing from types.
Related Skills
- superpowers:systematic-debugging — For bugs in your own code
- superpowers:test-driven-development — For creating failing test cases (Phase 4)
- superpowers:root-cause-tracing — For tracing bugs through call stacks