get_error_solutions
Find solutions for specific error messages by searching Claude conversation history to resolve coding problems.
Instructions
Find solutions for specific errors with enhanced matching
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| error_pattern | Yes | Error message or pattern to search for solutions | |
| limit | No | Maximum number of results (default: 8) | |
| detail_level | No | Response detail: summary (default), detailed, raw | summary |
Implementation Reference
- src/search.ts:925-1059 (handler)Core handler implementation in HistorySearchEngine.getErrorSolutions. Searches conversation JSONL files across projects for matching error patterns, collects subsequent assistant/tool_result messages as solutions, filters for quality, and returns structured ErrorSolution objects with frequency.async getErrorSolutions(errorPattern: string, limit: number = 10): Promise<ErrorSolution[]> { const solutions: ErrorSolution[] = []; const errorMap = new Map<string, CompactMessage[]>(); try { const projectDirs = await findProjectDirectories(); // BALANCED: More projects for better coverage, still much faster than sequential const limitedDirs = projectDirs.slice(0, 12); // Increased for better coverage // PARALLEL PROCESSING: Process all projects concurrently const projectResults = await Promise.allSettled( limitedDirs.map(async (projectDir) => { const jsonlFiles = await findJsonlFiles(projectDir); // BALANCED: More files for better coverage const limitedFiles = jsonlFiles.slice(0, 6); const projectErrorMap = new Map<string, CompactMessage[]>(); // PARALLEL: Process files within project simultaneously const fileResults = await Promise.allSettled( limitedFiles.map(async (file) => { const messages = await this.parser.parseJsonlFile(projectDir, file); // Find error patterns and their solutions for (let i = 0; i < messages.length - 1; i++) { const current = messages[i]; // More precise error matching - require significant overlap const lowerPattern = errorPattern.toLowerCase(); const patternWords = lowerPattern.split(/\s+/).filter((w) => w.length > 2); // Extract error type if present (TypeError, SyntaxError, etc.) const errorType = lowerPattern.match( /(typeerror|syntaxerror|referenceerror|rangeerror|error)/ )?.[0]; const hasMatchingError = current.context?.errorPatterns?.some((err) => { const lowerErr = err.toLowerCase(); // Require error type to match if specified if (errorType && !lowerErr.includes(errorType)) { return false; } // Require at least 3 pattern words to match, or full phrase match (stricter) if (lowerErr.includes(lowerPattern)) return true; const matchCount = patternWords.filter((w) => lowerErr.includes(w)).length; return matchCount >= Math.min(3, patternWords.length); }); // Only include if it's an actual error (not meta-discussion about errors) const isActualErrorContent = this.isActualError(current.content); // Filter out meta-content (plans, benchmarks, discussions) if ( (hasMatchingError || SearchHelpers.hasErrorInContent(current.content, errorPattern)) && isActualErrorContent && !this.isMetaErrorContent(current.content) ) { // Use the most relevant error pattern as key const matchedError = current.context?.errorPatterns?.find((err) => err.toLowerCase().includes(lowerPattern) ) || current.context?.errorPatterns?.[0] || errorPattern; const errorKey = matchedError; if (!projectErrorMap.has(errorKey)) { projectErrorMap.set(errorKey, []); } // Include the error message and the next few messages as potential solutions const solutionMessages = messages .slice(i, i + 8) // Get more context for better solutions (increased from 5 to 8) .filter( (msg) => msg.type === 'assistant' || msg.type === 'tool_result' || (msg.type === 'user' && msg.content.length < 200) // Include short user clarifications ); projectErrorMap.get(errorKey)!.push(...solutionMessages); } } }) ); return projectErrorMap; }) ); // Aggregate results from parallel processing for (const result of projectResults) { if (result.status === 'fulfilled') { const projectErrorMap = result.value; for (const [pattern, msgs] of projectErrorMap.entries()) { if (!errorMap.has(pattern)) { errorMap.set(pattern, []); } errorMap.get(pattern)!.push(...msgs); } } } // Convert to ErrorSolution format for (const [pattern, msgs] of errorMap.entries()) { // Assistant responses following errors are solutions by context // Lower threshold from 50 to 20 chars for actionable short solutions const qualitySolutions = msgs.filter( (msg) => msg.type === 'assistant' && !this.isLowValueContent(msg.content) && msg.content.length >= 20 ); if (qualitySolutions.length > 0) { solutions.push({ errorPattern: pattern, solution: qualitySolutions.slice(0, 5), // Include up to 5 solutions (increased from 3) context: SearchHelpers.extractSolutionContext(qualitySolutions), frequency: msgs.length, }); } } return solutions.sort((a, b) => b.frequency - a.frequency).slice(0, limit); } catch (error) { console.error('Error solution search error:', error); return []; } }
- src/index.ts:133-157 (registration)Tool registration in ListToolsRequestSchema handler, including name, description, and input schema.{ name: 'get_error_solutions', description: 'Find solutions for specific errors with enhanced matching', inputSchema: { type: 'object', properties: { error_pattern: { type: 'string', description: 'Error message or pattern to search for solutions', }, limit: { type: 'number', description: 'Maximum number of results (default: 8)', default: 8, }, detail_level: { type: 'string', description: 'Response detail: summary (default), detailed, raw', enum: ['summary', 'detailed', 'raw'], default: 'summary', }, }, required: ['error_pattern'], }, },
- src/index.ts:322-338 (handler)MCP server handler wrapper that delegates to UniversalHistorySearchEngine.getErrorSolutions and formats output.case 'get_error_solutions': { const universalResult = await this.universalEngine.getErrorSolutions( args?.error_pattern as string, (args?.limit as number) || 8 ); const detailLevel = (args?.detail_level as string) || 'summary'; const formattedResult = this.formatter.formatErrorSolutions( universalResult.results, args?.error_pattern as string, detailLevel ); return { content: [{ type: 'text', text: formattedResult }], }; }
- src/index.ts:136-156 (schema)Input schema definition for get_error_solutions tool.inputSchema: { type: 'object', properties: { error_pattern: { type: 'string', description: 'Error message or pattern to search for solutions', }, limit: { type: 'number', description: 'Maximum number of results (default: 8)', default: 8, }, detail_level: { type: 'string', description: 'Response detail: summary (default), detailed, raw', enum: ['summary', 'detailed', 'raw'], default: 'summary', }, }, required: ['error_pattern'], },
- src/formatter.ts:565-599 (helper)Helper formatter that structures and ranks error solutions output with robot emoji header and JSON response.formatErrorSolutions( solutions: ErrorSolution[], errorPattern: string, _detailLevel: string = 'summary' ): string { const header = `${robots.errorSolutions} "${errorPattern}" | ${solutions.length} solutions`; if (solutions.length === 0) { return `${header}\n\n{"solutions":[]}`; } const rankedSolutions = this.rankErrorSolutions(solutions); const topSolutions = rankedSolutions.slice(0, 5); const structured = { error_pattern: errorPattern, solutions: topSolutions.map((sol) => { // Include multiple fixes from all solutions, not just the first const fixes = sol.solution.map((s) => ({ content: s.content, code: s.context?.codeSnippets || null, files: s.context?.filesReferenced || null, })); return { pattern: sol.errorPattern, frequency: sol.frequency, fixes: fixes, ctx: sol.solution[0]?.context || null, }; }), }; return `${header}\n\n${JSON.stringify(structured, null, 2)}`; }