Troubleshooting
This guide covers common issues you may encounter when building with Zero, along with debugging strategies and solutions.Common Issues
SQLite NULL + OR = Full Table Scan
Problem: Queries with OR conditions involving NULL values perform full table scans instead of using indexes. Symptoms:- Query that should be fast (< 1ms) takes 100-300ms
- Performance degrades with table size
EXPLAIN QUERY PLANshowsSCANinstead ofSEARCH
Query Not Updating
Problem: UI doesn’t reflect data changes even though mutations succeed. Possible causes:-
Query not subscribed to changes:
-
Query destroyed prematurely:
-
Mutation not pushed to server:
-
Schema mismatch between client and server:
- Verify client and server use the same schema version
- Check for schema migration issues
Memory Leaks
Problem: Memory usage grows over time, eventually causing performance degradation or crashes. Symptoms:- Increasing memory usage in browser dev tools
- Slowing performance over time
- “Out of memory” errors
-
Queries not cleaned up:
-
Event listeners not removed:
-
Large result sets retained in memory:
-
Use browser memory profiler:
- Chrome DevTools → Memory → Take heap snapshot
- Look for growing object counts (especially
Node,Operatorinstances)
-
Check for retained queries:
Slow Query Performance
Problem: Queries take longer than expected to materialize or update. Diagnosis steps:-
Measure materialization time:
-
Check for missing indexes:
-
Verify ANALYZE has been run:
-
Analyze query plan:
-
Profile with OpenTelemetry:
- Add indexes on join columns
- Run ANALYZE to update statistics
- Add filters to reduce result set size
- Use limits to cap result count
- Restructure deeply nested queries
Type Errors
Problem: TypeScript compilation errors in query or mutation code. Common issues:-
Schema type mismatch:
-
Incorrect query builder types:
-
Missing type imports:
type | undefined, not just type?:
Mutation Conflicts
Problem: Mutations fail with conflict errors or produce unexpected results. Symptoms:- “Version mismatch” errors
- Mutations silently failing
- Data reverting after mutation
-
Concurrent edits:
-
Stale client state:
- Client offline for extended period
- Server state changed significantly
- Client needs to re-sync
-
Invalid mutation logic:
-
Implement optimistic UI with rollback:
-
Use last-write-wins semantics when appropriate:
-
Add conflict resolution logic:
Debugging Techniques
Enable Debug Logging
Client-side:Inspect Query AST
Trace Operator Pipeline
Use Browser DevTools
Network tab:- Monitor WebSocket messages (mutations, sync)
- Check for failed requests
- Verify timing and payload sizes
- Record query execution
- Identify bottlenecks
- Check for excessive re-renders
- Take heap snapshots
- Compare snapshots over time
- Find retained objects
Database Inspection
SQLite (client-side):Test Isolation
Isolate the issue:-
Minimal reproduction:
-
Test with synthetic data:
-
Compare with direct SQL:
Error Messages
QueryParseError
Message:Failed to parse arguments for query
Cause: Invalid arguments passed to query builder
Solution:
packages/zql/src/query/error.ts
Connection Errors
Message:Failed to connect to Zero cache
Common causes:
- Zero cache not running
- Incorrect URL configuration
- Network issues
Schema Errors
Message:Table 'xyz' not found in schema
Cause: Query references table not in schema
Solution:
Performance Debugging
Identify Bottlenecks
-
Measure each operation:
-
Profile operator pipeline:
-
Monitor metrics:
Analyze Query Plans
- High costs → Add indexes or filters
- Wrong plan selected → Update statistics (ANALYZE)
- All plans expensive → Restructure query
Common Error Patterns
Pattern: Edit Change Split
Symptom: Edit changes become remove + add in UI Cause: Filter condition changed or sort order affected Expected behavior:packages/zql/src/ivm/view-apply-change.ts:46.
Pattern: Relationship Stream Exhausted
Symptom: Error when iterating relationship twice Cause: Relationship streams are single-use Solution:Pattern: Yield Not Propagated
Symptom: UI freezes during large operations Cause: Yield signals not propagated through pipeline Contract: If an operation yields'yield', caller must yield immediately.
packages/zql/src/ivm/operator.ts:41.
Getting Help
Before Asking
- Search existing issues on GitHub
- Check this troubleshooting guide
- Review Performance best practices
- Try isolating the issue to minimal reproduction
What to Include
-
Minimal reproduction:
- Simplest code that shows the issue
- Sample schema and data
- Expected vs actual behavior
-
Environment:
- Zero version
- Browser/Node.js version
- Operating system
-
Error messages:
- Full stack trace
- Console logs
- Network errors (if applicable)
-
What you’ve tried:
- Steps already taken
- Debugging output
- Related issues checked
Resources
- GitHub Issues: https://github.com/rocicorp/mono
- Documentation: https://zero.rocicorp.dev
- Discord: https://discord.gg/rocicorp
Next Steps
- Optimize performance with Performance guide
- Understand internals in ZQL Engine deep dive
- Plan upgrades using Migration strategies