skills/development-skills/serverless-debugging/SKILL.md
Debug serverless and edge functions where traditional logging is limited. Use when features are deployed but not triggering, logs are missing, or runtime behavior differs from expectations in Supabase Edge Functions, AWS Lambda, Cloudflare Workers, or similar platforms.
npx skillsauth add abcnuts/manus-skills serverless-debuggingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Systematic debugging methodology for serverless/edge functions where console.log may not appear in logs and traditional debugging tools are unavailable.
Collect evidence from ALL layers before forming hypotheses. Avoid jumping to conclusions.
Database Layer:
Code Layer:
Runtime Layer:
Environment Layer:
Evidence Checklist: See references/evidence-checklist.md for comprehensive list
Compare working vs. broken behavior to identify differences.
Key Questions:
Common Patterns:
Form specific, testable hypotheses based on evidence.
Good Hypothesis Characteristics:
Example Hypotheses:
Testing Without Logs:
Fix the root cause and verify across all layers.
Fix Implementation:
Verification:
See references/common-serverless-bugs.md for detailed catalog. Quick reference:
Type Coercion Issues:
0 === null → false (check for both)undefined === null → falseAsync/Timing Issues:
Environment Differences:
Database Issues:
When console.log doesn't work, use these alternatives:
Database-Driven Debugging:
-- Create debug log table
CREATE TABLE debug_logs (
id SERIAL PRIMARY KEY,
timestamp TIMESTAMPTZ DEFAULT NOW(),
function_name TEXT,
checkpoint TEXT,
data JSONB
);
-- Write debug info from code
INSERT INTO debug_logs (function_name, checkpoint, data)
VALUES ('my-function', 'before-extraction', jsonb_build_object('count', message_count));
Error Response Debugging:
// Return diagnostic info in error response
return new Response(JSON.stringify({
debug: {
messageCount: messageCount,
lastExtraction: lastExtraction,
shouldExtract: shouldExtractMemories(messageCount, lastExtraction)
}
}), { status: 200 });
Code Analysis:
See references/logging-alternatives.md for more strategies.
Deployment Verification:
# Use scripts/check_deployment.py
python scripts/check_deployment.py <function-name> <local-path>
Database State Analysis:
# Use scripts/database_debugger.py
python scripts/database_debugger.py <table-name> <condition>
Type Analysis:
# Use scripts/type_analyzer.py
python scripts/type_analyzer.py <file-path> <function-name>
Symptom: Proactive memory extraction never triggered despite code being deployed.
Phase 1 Evidence:
last_extraction_at stayed at 0Phase 2 Pattern:
Phase 3 Hypothesis:
last_extraction_at is 0, not nullif (lastExtraction === null) → always false when 0messageCount - 0 >= 10 instead of messageCount >= 4Phase 4 Fix:
// Before: Only checked null
if (lastExtractionAt === null) {
return messageCount >= 4;
}
// After: Check both null AND 0
if (lastExtractionAt === null || lastExtractionAt === 0) {
return messageCount >= 4;
}
Result: Feature now works correctly, triggers after 4 messages.
references/evidence-checklist.md and gather evidence from all layersscripts/ tools to verify hypothesisRed flag pattern: Multiple fix attempts, each revealing new problems in different layers.
Pattern: Not converging on a solution. Each fix reveals a NEW problem.
Per systematic-debugging Phase 4.5:
If 3+ fixes failed: STOP and question the architecture
This is NOT a bug. This is an ARCHITECTURAL PROBLEM.
The real issues:
STOP attempting more fixes. Instead:
Get better error visibility
references/enhanced-error-logging.md)Simplify the workflow
Question the fundamentals
Attempts:
Root cause: Generic error message hid the actual Stripe error
Solution: Add comprehensive error logging to see real error, then fix that
Lesson: After 3 failed fixes, we should have stopped and added better logging FIRST
See also: systematic-debugging skill Phase 4.5
Problem: Module-level initialization fails in serverless environments.
// ❌ DON'T: Initialize at module load
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
Why it fails:
Solution: Lazy initialization pattern
// ✅ DO: Initialize on first use
let stripeInstance = null;
function getStripe() {
if (!stripeInstance) {
const key = process.env.STRIPE_SECRET_KEY;
if (!key) throw new Error('STRIPE_SECRET_KEY not set');
stripeInstance = require('stripe')(key);
}
return stripeInstance;
}
Benefits:
See references/lazy-initialization-patterns.md for complete examples.
Problem: Generic error messages hide root cause.
// ❌ DON'T: Hide error details
catch (error) {
res.status(500).json({ error: 'An error occurred' });
}
Solution: Log full error details
// ✅ DO: Log comprehensive error info
catch (error) {
console.error('Operation failed:', {
message: error.message,
type: error.type,
code: error.code,
stack: error.stack,
context: { priceId, userId }
});
res.status(500).json({
error: error.message,
type: error.type,
code: error.code
});
}
See references/enhanced-error-logging.md for patterns.
Add health check endpoints to verify configuration:
app.get('/api/health', (req, res) => {
const config = {
stripe: !!process.env.STRIPE_SECRET_KEY,
supabase: !!process.env.SUPABASE_URL
};
const keyPrefixes = {
stripe: config.stripe ? process.env.STRIPE_SECRET_KEY.substring(0, 7) : 'none'
};
res.json({
status: 'ok',
configured: config,
keyPrefixes: keyPrefixes
});
});
Usage:
curl https://your-api.vercel.app/api/health
This immediately shows:
tools
Generate comprehensive demonstrations showing how to access projects and work across different environments (Manus terminals, personal computers, team collaboration). Use when users ask "how do I access this from another terminal/computer", "how do I share this with my team", "how do I get this on my Mac", or need clarification on Manus persistence vs GitHub usage.
development
Use when you have a spec or requirements for a multi-step task, before touching code
data-ai
Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
development
Use when implementing any feature or bugfix, before writing implementation code