**Callsign:** Recognizer
Matches error patterns to known issues and suggests instant fixes from a knowledge base.
/plugin marketplace add markus41/claude/plugin install debug-detective@claude-orchestrationCallsign: Recognizer Model: sonnet Role: Common Error Pattern Matching & Known Issue Detection
Recognizes common error patterns from a knowledge base of known issues. Provides instant solutions for frequently-encountered bugs and suggests probable fixes based on similar historical issues.
const patterns = {
"cannot_read_property": {
regex: /Cannot read propert(y|ies) ['\"](\w+)['\"]/,
category: "null_pointer",
commonCauses: [
"Object is null or undefined",
"Async data not loaded yet",
"Optional property missing",
"Wrong object shape from API"
],
solutions: [
{
name: "Optional Chaining",
code: "obj?.property",
whenToUse: "When property might not exist"
},
{
name: "Null Check",
code: "if (obj && obj.property) { ... }",
whenToUse: "When you need to handle null case"
},
{
name: "Default Value",
code: "obj?.property ?? 'default'",
whenToUse: "When you can use a fallback"
},
{
name: "Loading State",
code: "if (loading) return <Spinner />;",
whenToUse: "For async data in React"
}
],
diagnosticQuestions: [
"Is this variable from an async operation?",
"Could the object be null/undefined at this point?",
"Is the property always present on this object type?"
]
},
"maximum_call_stack": {
regex: /Maximum call stack size exceeded/,
category: "stack_overflow",
commonCauses: [
"Infinite recursion (missing base case)",
"Circular dependency",
"Event listener causing re-trigger",
"useState/setState in render causing loop"
],
solutions: [
{
name: "Add Base Case",
code: `
function recursive(n) {
if (n <= 0) return; // ← Base case
recursive(n - 1);
}
`,
whenToUse: "For recursive functions"
},
{
name: "Break Circular Dependency",
code: "Use dependency injection or lazy loading",
whenToUse: "When two modules import each other"
},
{
name: "Move setState Outside Render",
code: "Use useEffect for side effects",
whenToUse: "React infinite render loop"
}
],
debugging: [
"Look for repeating function names in stack trace",
"Check for circular imports with webpack/rollup",
"Use React DevTools profiler to find render loops"
]
},
"hydration_mismatch": {
regex: /Hydration failed|Text content does not match/,
category: "react_ssr",
commonCauses: [
"Server rendered different content than client",
"Using Date.now() or random values",
"Browser-only APIs during SSR",
"Conditional rendering based on client state"
],
solutions: [
{
name: "Suppress Hydration Warning",
code: "<div suppressHydrationWarning>{clientOnlyValue}</div>",
whenToUse: "When client/server difference is intentional"
},
{
name: "Use useEffect for Client-Only Code",
code: `
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null;
`,
whenToUse: "For browser-only features"
},
{
name: "Consistent Data",
code: "Pass server timestamp to client, don't generate new one",
whenToUse: "When using time-based values"
}
]
},
"cors_error": {
regex: /CORS|No 'Access-Control-Allow-Origin'/,
category: "network",
commonCauses: [
"API doesn't allow origin",
"Missing credentials in request",
"Preflight request failing",
"Wrong headers configuration"
],
solutions: [
{
name: "Server-Side CORS Headers",
code: `
res.header('Access-Control-Allow-Origin', 'https://yoursite.com');
res.header('Access-Control-Allow-Credentials', 'true');
`,
whenToUse: "When you control the backend"
},
{
name: "Proxy in Development",
code: `
// In vite.config.ts
proxy: {
'/api': 'http://localhost:3000'
}
`,
whenToUse: "For development environment"
},
{
name: "Use Server-Side Fetching",
code: "Fetch from server (Next.js getServerSideProps)",
whenToUse: "When backend can't add CORS headers"
}
]
},
"promise_rejection": {
regex: /UnhandledPromiseRejection|Unhandled promise rejection/,
category: "async",
commonCauses: [
"Missing try-catch around await",
"No .catch() on promise chain",
"Error in async function not handled",
"Promise rejection in event handler"
],
solutions: [
{
name: "Try-Catch",
code: `
try {
await asyncOperation();
} catch (error) {
handleError(error);
}
`,
whenToUse: "With async/await"
},
{
name: "Catch Handler",
code: "promise.then(result => ...).catch(error => ...)",
whenToUse: "With promise chains"
},
{
name: "Global Handler",
code: "process.on('unhandledRejection', (error) => ...)",
whenToUse: "As last resort / logging"
}
]
}
};
const reactPatterns = {
"infinite_render_loop": {
symptoms: [
"Browser freezes/crashes",
"React DevTools shows 1000+ renders",
"Error: Too many re-renders"
],
commonCauses: [
"setState in render body",
"useEffect missing dependency",
"useEffect with no dependency array",
"Object/array in dependency array (new reference each render)"
],
solutions: [
{
problem: "setState in render",
bad: `
function Component() {
setState(value); // ← Triggers re-render infinitely
return <div>...</div>;
}
`,
good: `
function Component() {
useEffect(() => {
setState(value); // ✓ In effect
}, []);
return <div>...</div>;
}
`
},
{
problem: "Unstable dependency",
bad: `
useEffect(() => {
fetchData();
}, [{ userId }]); // ← New object each render
`,
good: `
useEffect(() => {
fetchData();
}, [userId]); // ✓ Stable primitive
`
}
]
},
"stale_closure": {
symptoms: [
"Event handler uses old state",
"setTimeout/setInterval sees stale values",
"Callback uses outdated props"
],
solutions: [
{
name: "Use Ref for Latest Value",
code: `
const latestValue = useRef(value);
latestValue.current = value;
const callback = useCallback(() => {
console.log(latestValue.current); // Always latest
}, []);
`
},
{
name: "Use Functional Update",
code: "setState(prev => prev + 1) // ← Gets latest state"
}
]
}
};
function matchErrorPattern(error: ErrorMessage): PatternMatch[] {
const matches: PatternMatch[] = [];
for (const [name, pattern] of Object.entries(patterns)) {
const match = error.message.match(pattern.regex);
if (match) {
const confidence = calculateConfidence(error, pattern);
matches.push({
patternName: name,
confidence,
category: pattern.category,
solutions: pattern.solutions,
diagnosticQuestions: pattern.diagnosticQuestions
});
}
}
// Also check for similar historical issues
const historical = findSimilarHistoricalIssues(error);
matches.push(...historical);
return matches.sort((a, b) => b.confidence - a.confidence);
}
function calculateConfidence(error: ErrorMessage, pattern: Pattern): number {
let score = 50; // Base for regex match
// Stack trace contains pattern-specific frames
if (pattern.suspiciousFrames?.some(frame => error.stack.includes(frame))) {
score += 20;
}
// Error occurs in pattern-specific file types
if (pattern.fileTypes?.some(ext => error.file.endsWith(ext))) {
score += 15;
}
// Code context contains pattern indicators
if (pattern.codeIndicators?.some(indicator => error.codeContext.includes(indicator))) {
score += 15;
}
return Math.min(score, 100);
}
Error: Cannot read property 'email' of undefined
at UserProfile (components/UserProfile.tsx:42)
at render (react-dom)
const analysis = {
error: "Cannot read property 'email' of undefined",
matchedPatterns: [
{
pattern: "cannot_read_property",
confidence: 95,
matched: {
property: "email",
extractedFrom: "Cannot read property 'email'"
},
diagnosis: {
likelyCause: "The object containing 'email' is undefined",
possibleReasons: [
"user.profile is undefined (most likely based on property name)",
"user is undefined",
"Async data not loaded yet"
],
quickFixes: [
{
priority: 1,
description: "Add optional chaining",
code: "const email = user?.profile?.email;",
tradeoff: "Returns undefined instead of crashing, need to handle undefined case"
},
{
priority: 2,
description: "Add loading state",
code: `
if (!user) return <Loading />;
const email = user.profile.email;
`,
tradeoff: "Better UX but requires loading component"
}
]
},
historicalExamples: [
{
issue: "JIRA-123: User profile page crashes",
resolution: "Added null check for profile",
similarity: 0.92
},
{
issue: "JIRA-456: Email display error",
resolution: "Changed API to always include profile field",
similarity: 0.85
}
],
relatedDocumentation: [
"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining",
"https://react.dev/learn/conditional-rendering"
]
}
],
recommendation: {
immediate: "Add optional chaining: user?.profile?.email",
investigative: "Check why profile is undefined - is API response missing it?",
preventive: "Add TypeScript strict null checks to catch this at compile time"
}
};
async function learnFromResolution(issue: ResolvedIssue) {
const pattern = {
errorSignature: generateSignature(issue.error),
symptoms: issue.symptoms,
rootCause: issue.rootCause,
solution: issue.solution,
timeToResolve: issue.resolutionTime,
effectiveness: issue.solutionEffectiveness
};
// Add to knowledge base
await knowledgeBase.add(pattern);
// Update existing pattern confidence if similar
const similar = await knowledgeBase.findSimilar(pattern, threshold = 0.8);
if (similar) {
similar.occurrences++;
similar.solutions.push(issue.solution);
similar.confidence = updateConfidence(similar);
}
}
Receives:
Provides:
Delegates To:
Designs feature architectures by analyzing existing codebase patterns and conventions, then providing comprehensive implementation blueprints with specific files to create/modify, component designs, data flows, and build sequences