fix: Chroma connection errors and remove dead last_user_message code (#525)
* fix: distinguish connection errors from collection-not-found in ChromaSync Previously, ensureCollection() caught ALL errors from chroma_get_collection_info and assumed they meant "collection doesn't exist". This caused connection errors like "Not connected" to trigger unnecessary collection creation attempts. Now connection-related errors are re-thrown immediately instead of being misinterpreted as missing collections. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: improve error handling for Chroma connection and collection creation * fix: remove dead last_user_message from summarize flow The last_user_message field was extracted from transcripts but never used. In Claude Code transcripts, "user" type messages are mostly tool_results, not actual user input. The user's original request is already stored in user_prompts table. This removes the false warning "Missing last_user_message when queueing summary" which was complaining about missing data that didn't exist and wasn't needed. Changes: - summary-hook: Only extract last_assistant_message - SessionRoutes: Remove last_user_message from request body handling - SessionManager.queueSummarize: Remove lastUserMessage parameter - PendingMessage interface: Remove last_user_message field - SDKSession interface: Remove last_user_message field - All agents: Remove last_user_message from buildSummaryPrompt calls 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * build artifacts for plugin * Enhance error handling across multiple services - Improved logging in `BranchManager.ts` to capture recovery checkout failures. - Updated `PaginationHelper.ts` to log when file paths are plain strings instead of valid JSON. - Enhanced error logging in `SDKAgent.ts` for Claude executable detection failures. - Added logging for plain string handling in `SearchManager.ts` for files read and edited. - Improved logging in `paths.ts` for git root detection failures. - Enhanced JSON parsing error handling in `timeline-formatting.ts` with previews of failed inputs. - Updated `transcript-parser.ts` to log summary of parse errors after processing transcript lines. - Established a baseline for error handling practices in `error-handling-baseline.txt`. - Documented error handling anti-pattern rules in `CLAUDE.md` to prevent silent failures and improve code quality. * Add error handling anti-pattern detection script and guidelines - Introduced `detect-error-handling-antipatterns.ts` to identify common error handling issues in TypeScript code. - Created comprehensive documentation in `CLAUDE.md` outlining forbidden patterns, allowed patterns, and critical path protection rules. - Implemented checks for empty catch blocks, logging practices, and try-catch block sizes to prevent silent failures and improve debugging. - Established a reporting mechanism to summarize detected anti-patterns with severity levels. * feat: add console filter bar and log line parsing with filtering capabilities - Introduced a console filter bar with options to filter logs by level and component. - Implemented parsing of log lines to extract structured data including timestamp, level, component, and correlation ID. - Added functionality to toggle individual and all levels/components for filtering. - Enhanced log line rendering with color coding based on log level and special message types. - Improved responsiveness of the filter bar for smaller screens. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -240,8 +240,9 @@ export async function switchBranch(targetBranch: string): Promise<SwitchResult>
|
||||
if (info.branch && isValidBranchName(info.branch)) {
|
||||
execGit(['checkout', info.branch]);
|
||||
}
|
||||
} catch {
|
||||
// Recovery failed, user needs manual intervention
|
||||
} catch (recoveryError) {
|
||||
// [POSSIBLY RELEVANT]: Recovery checkout failed, user needs manual intervention - already logging main error above
|
||||
logger.warn('BRANCH', 'Recovery checkout also failed', { originalBranch: info.branch }, recoveryError as Error);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -229,7 +229,6 @@ export class GeminiAgent {
|
||||
memory_session_id: session.memorySessionId,
|
||||
project: session.project,
|
||||
user_prompt: session.userPrompt,
|
||||
last_user_message: message.last_user_message || '',
|
||||
last_assistant_message: message.last_assistant_message || ''
|
||||
}, mode);
|
||||
|
||||
|
||||
@@ -188,7 +188,6 @@ export class OpenRouterAgent {
|
||||
memory_session_id: session.memorySessionId,
|
||||
project: session.project,
|
||||
user_prompt: session.userPrompt,
|
||||
last_user_message: message.last_user_message || '',
|
||||
last_assistant_message: message.last_assistant_message || ''
|
||||
}, mode);
|
||||
|
||||
|
||||
@@ -52,8 +52,7 @@ export class PaginationHelper {
|
||||
// Return as JSON string
|
||||
return JSON.stringify(strippedPaths);
|
||||
} catch (err) {
|
||||
// Expected: file paths may not be valid JSON (plain string)
|
||||
// Not logging - normal fallback for non-JSON file path strings
|
||||
logger.debug('WORKER', 'File paths is plain string, using as-is', {}, err as Error);
|
||||
return filePathsStr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,6 @@ export class SDKAgent {
|
||||
memory_session_id: session.memorySessionId,
|
||||
project: session.project,
|
||||
user_prompt: session.userPrompt,
|
||||
last_user_message: message.last_user_message || '',
|
||||
last_assistant_message: message.last_assistant_message || ''
|
||||
}, mode);
|
||||
|
||||
@@ -544,7 +543,8 @@ export class SDKAgent {
|
||||
|
||||
if (claudePath) return claudePath;
|
||||
} catch (error) {
|
||||
logger.debug('SDK', 'Claude executable auto-detection failed', error);
|
||||
// [ANTI-PATTERN IGNORED]: Fallback behavior - which/where failed, continue to throw clear error
|
||||
logger.debug('SDK', 'Claude executable auto-detection failed', {}, error as Error);
|
||||
}
|
||||
|
||||
throw new Error('Claude executable not found. Please either:\n1. Add "claude" to your system PATH, or\n2. Set CLAUDE_CODE_PATH in ~/.claude-mem/settings.json');
|
||||
|
||||
@@ -1401,8 +1401,7 @@ export class SearchManager {
|
||||
lines.push(`**Files Read:** ${filesRead.join(', ')}`);
|
||||
}
|
||||
} catch (error) {
|
||||
// Expected: files_read may not be valid JSON (plain string)
|
||||
// Not logging - normal fallback for plain text file lists
|
||||
logger.debug('WORKER', 'files_read is plain string, using as-is', {}, error as Error);
|
||||
if (summary.files_read.trim()) {
|
||||
lines.push(`**Files Read:** ${summary.files_read}`);
|
||||
}
|
||||
@@ -1417,8 +1416,7 @@ export class SearchManager {
|
||||
lines.push(`**Files Edited:** ${filesEdited.join(', ')}`);
|
||||
}
|
||||
} catch (error) {
|
||||
// Expected: files_edited may not be valid JSON (plain string)
|
||||
// Not logging - normal fallback for plain text file lists
|
||||
logger.debug('WORKER', 'files_edited is plain string, using as-is', {}, error as Error);
|
||||
if (summary.files_edited.trim()) {
|
||||
lines.push(`**Files Edited:** ${summary.files_edited}`);
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ export class SessionManager {
|
||||
* CRITICAL: Persists to database FIRST before adding to in-memory queue.
|
||||
* This ensures summarize requests survive worker crashes.
|
||||
*/
|
||||
queueSummarize(sessionDbId: number, lastUserMessage: string, lastAssistantMessage?: string): void {
|
||||
queueSummarize(sessionDbId: number, lastAssistantMessage?: string): void {
|
||||
// Auto-initialize from database if needed (handles worker restarts)
|
||||
let session = this.sessions.get(sessionDbId);
|
||||
if (!session) {
|
||||
@@ -244,7 +244,6 @@ export class SessionManager {
|
||||
// CRITICAL: Persist to database FIRST
|
||||
const message: PendingMessage = {
|
||||
type: 'summarize',
|
||||
last_user_message: lastUserMessage,
|
||||
last_assistant_message: lastAssistantMessage
|
||||
};
|
||||
|
||||
|
||||
@@ -338,9 +338,9 @@ export class SessionRoutes extends BaseRouteHandler {
|
||||
const sessionDbId = this.parseIntParam(req, res, 'sessionDbId');
|
||||
if (sessionDbId === null) return;
|
||||
|
||||
const { last_user_message, last_assistant_message } = req.body;
|
||||
const { last_assistant_message } = req.body;
|
||||
|
||||
this.sessionManager.queueSummarize(sessionDbId, last_user_message, last_assistant_message);
|
||||
this.sessionManager.queueSummarize(sessionDbId, last_assistant_message);
|
||||
|
||||
// CRITICAL: Ensure SDK agent is running to consume the queue
|
||||
this.ensureGeneratorRunning(sessionDbId, 'summarize');
|
||||
@@ -492,12 +492,12 @@ export class SessionRoutes extends BaseRouteHandler {
|
||||
/**
|
||||
* Queue summarize by contentSessionId (summary-hook uses this)
|
||||
* POST /api/sessions/summarize
|
||||
* Body: { contentSessionId, last_user_message, last_assistant_message }
|
||||
* Body: { contentSessionId, last_assistant_message }
|
||||
*
|
||||
* Checks privacy, queues summarize request for SDK agent
|
||||
*/
|
||||
private handleSummarizeByClaudeId = this.wrapHandler((req: Request, res: Response): void => {
|
||||
const { contentSessionId, last_user_message, last_assistant_message } = req.body;
|
||||
const { contentSessionId, last_assistant_message } = req.body;
|
||||
|
||||
if (!contentSessionId) {
|
||||
return this.badRequest(res, 'Missing contentSessionId');
|
||||
@@ -523,17 +523,7 @@ export class SessionRoutes extends BaseRouteHandler {
|
||||
}
|
||||
|
||||
// Queue summarize
|
||||
this.sessionManager.queueSummarize(
|
||||
sessionDbId,
|
||||
last_user_message || logger.happyPathError(
|
||||
'SESSION',
|
||||
'Missing last_user_message when queueing summary in SessionRoutes',
|
||||
{ sessionId: sessionDbId },
|
||||
undefined,
|
||||
''
|
||||
),
|
||||
last_assistant_message
|
||||
);
|
||||
this.sessionManager.queueSummarize(sessionDbId, last_assistant_message);
|
||||
|
||||
// Ensure SDK agent is running
|
||||
this.ensureGeneratorRunning(sessionDbId, 'summarize');
|
||||
|
||||
Reference in New Issue
Block a user