diff --git a/src/tools/memories.ts b/src/tools/memories.ts index 84930d0..4484bed 100644 --- a/src/tools/memories.ts +++ b/src/tools/memories.ts @@ -43,10 +43,24 @@ interface MemoryListArgs { /** * Add a new memory/learning (enhanced with session_id and task_id) + * CF-306: Validates session_id exists before inserting to prevent foreign key violations */ export async function memoryAdd(args: MemoryAddArgs): Promise { const { category, title, content, context, project, session_id, task_id } = args; + // CF-306: Validate session_id exists if provided + let validSessionId = session_id || null; + if (session_id) { + const sessionExists = await queryOne<{ exists: boolean }>( + `SELECT EXISTS(SELECT 1 FROM sessions WHERE id = $1) as exists`, + [session_id] + ); + if (!sessionExists?.exists) { + console.warn(`[CF-306] Session ${session_id} not found in database - using NULL instead`); + validSessionId = null; + } + } + // Generate embedding for semantic search const embedText = `${title}. ${content}`; const embedding = await getEmbedding(embedText); @@ -56,13 +70,13 @@ export async function memoryAdd(args: MemoryAddArgs): Promise { await execute( `INSERT INTO memories (category, title, content, context, project, session_id, task_id, embedding) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, - [category, title, content, context || null, project || null, session_id || null, task_id || null, embeddingValue] + [category, title, content, context || null, project || null, validSessionId, task_id || null, embeddingValue] ); } else { await execute( `INSERT INTO memories (category, title, content, context, project, session_id, task_id) VALUES ($1, $2, $3, $4, $5, $6, $7)`, - [category, title, content, context || null, project || null, session_id || null, task_id || null] + [category, title, content, context || null, project || null, validSessionId, task_id || null] ); }