From 84281015cf3ef856bd89d3bb1a11f7e6807cdc0a Mon Sep 17 00:00:00 2001 From: Felipe Parra Date: Tue, 9 Dec 2025 15:11:35 -0300 Subject: [PATCH 1/4] fix: add database initialization delay to prevent race condition - Add 3-second delay before initial decay process - Prevent race condition where decay runs before SQLite is ready - Add diagnostic logging to show memory count on startup - Add warnings for initialization failures This fixes an issue where existing memories in SQLite don't load on container restart or version upgrade. The delay ensures the database connection is fully established before querying memories. --- backend/src/memory/hsg.ts | 12 ++++++++++++ backend/src/server/index.ts | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/backend/src/memory/hsg.ts b/backend/src/memory/hsg.ts index 101831da..bf3e68d2 100644 --- a/backend/src/memory/hsg.ts +++ b/backend/src/memory/hsg.ts @@ -993,7 +993,17 @@ export async function run_decay_process(): Promise<{ processed: number; decayed: number; }> { + console.log('[DECAY] Querying memories from database...'); const mems = await q.all_mem.all(10000, 0); + console.log(`[DECAY] Retrieved ${mems.length} memories from database`); + + if (mems.length === 0) { + console.error('[DECAY] ⚠️ WARNING: No memories retrieved! Possible causes:'); + console.error('[DECAY] - Database not initialized'); + console.error('[DECAY] - Wrong database path'); + console.error('[DECAY] - Database file is empty'); + } + let p = 0, d = 0; for (const m of mems) { @@ -1006,6 +1016,8 @@ export async function run_decay_process(): Promise<{ p++; } if (d > 0) await log_maint_op("decay", d); + + console.log(`[DECAY] Completed: Processed ${p} memories, updated ${d}`); return { processed: p, decayed: d }; } export async function add_hsg_memory( diff --git a/backend/src/server/index.ts b/backend/src/server/index.ts index e6c8b79b..d75edb46 100644 --- a/backend/src/server/index.ts +++ b/backend/src/server/index.ts @@ -98,13 +98,22 @@ setInterval( }, 7 * 24 * 60 * 60 * 1000, ); -run_decay_process() - .then((result: any) => { +// Wait for database initialization before running decay +// This prevents race conditions where decay runs before SQLite is fully ready +setTimeout(async () => { + try { + console.log('[INIT] Starting delayed decay process to ensure database is ready...'); + const result = await run_decay_process(); console.log( `[INIT] Initial decay: ${result.decayed}/${result.processed} memories updated`, ); - }) - .catch(console.error); + if (result.processed === 0) { + console.warn('[INIT] ⚠️ WARNING: No memories were processed! Database may not be initialized.'); + } + } catch (error) { + console.error("[INIT] Initial decay failed:", error); + } +}, 3000); // 3 second delay to ensure database connection is established start_reflection(); start_user_summary_reflection(); From 768f7b66b4dc289de8008a0db3d9aba594a2643a Mon Sep 17 00:00:00 2001 From: Felipe Parra Date: Tue, 9 Dec 2025 15:27:03 -0300 Subject: [PATCH 2/4] refactor: address Copilot review feedback - Replace console.error with console.warn for warning messages in hsg.ts - Extract magic number 3000 to DB_INIT_DELAY_MS constant - Make initialization delay configurable via OM_DB_INIT_DELAY_MS env var - Improves code maintainability and semantic correctness --- backend/src/memory/hsg.ts | 8 ++++---- backend/src/server/index.ts | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/backend/src/memory/hsg.ts b/backend/src/memory/hsg.ts index bf3e68d2..488602d7 100644 --- a/backend/src/memory/hsg.ts +++ b/backend/src/memory/hsg.ts @@ -998,10 +998,10 @@ export async function run_decay_process(): Promise<{ console.log(`[DECAY] Retrieved ${mems.length} memories from database`); if (mems.length === 0) { - console.error('[DECAY] ⚠️ WARNING: No memories retrieved! Possible causes:'); - console.error('[DECAY] - Database not initialized'); - console.error('[DECAY] - Wrong database path'); - console.error('[DECAY] - Database file is empty'); + console.warn('[DECAY] ⚠️ WARNING: No memories retrieved! Possible causes:'); + console.warn('[DECAY] - Database not initialized'); + console.warn('[DECAY] - Wrong database path'); + console.warn('[DECAY] - Database file is empty'); } let p = 0, diff --git a/backend/src/server/index.ts b/backend/src/server/index.ts index d75edb46..bdfb229a 100644 --- a/backend/src/server/index.ts +++ b/backend/src/server/index.ts @@ -21,6 +21,10 @@ const ASC = ` ____ __ __ | | __/ | |_| |___/ `; +// Database initialization delay in milliseconds +// Allows time for SQLite connection to be fully established before running decay +const DB_INIT_DELAY_MS = parseInt(process.env.OM_DB_INIT_DELAY_MS || '3000', 10); + const app = server({ max_payload_size: env.max_payload_size }); console.log(ASC); @@ -113,7 +117,7 @@ setTimeout(async () => { } catch (error) { console.error("[INIT] Initial decay failed:", error); } -}, 3000); // 3 second delay to ensure database connection is established +}, DB_INIT_DELAY_MS); start_reflection(); start_user_summary_reflection(); From c337dcaff2977841579f89e82261c8009c888f86 Mon Sep 17 00:00:00 2001 From: Felipe Parra Date: Fri, 19 Dec 2025 14:36:33 -0300 Subject: [PATCH 3/4] chore: update .gitignore - ignore tool configs and IDEs --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 94c630d7..2a39cc01 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,4 @@ exports *.egg-info *.vsix __pycache__ -test \ No newline at end of file +test.chunkhound/ From 41065a3f0600bba6944847918e14bc1b16845bcf Mon Sep 17 00:00:00 2001 From: Felipe Parra Date: Fri, 19 Dec 2025 16:20:15 -0300 Subject: [PATCH 4/4] refactor: move OM_DB_INIT_DELAY_MS to centralized config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add db_init_delay_ms to env object in cfg.ts - Remove hardcoded DB_INIT_DELAY_MS from server/index.ts - Add documentation to .env.example with default value (3000ms) - Maintains backward compatibility with default value Tested on macOS with Docker: - 0ms delay: ✅ 354/354 memories loaded - 1000ms delay: ✅ 354/354 memories loaded - 3000ms delay: ✅ 354/354 memories loaded (default) - 5000ms delay: ✅ 354/354 memories loaded - Empty database: ✅ Graceful handling All tests pass with no TypeScript errors. --- .env.example | 6 ++++++ backend/src/core/cfg.ts | 1 + backend/src/server/index.ts | 10 +++------- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index 37301da5..3b98414a 100644 --- a/.env.example +++ b/.env.example @@ -29,6 +29,12 @@ OM_TELEMETRY=true # Server Mode OM_MODE=standard # standard | langgraph +# Database Initialization Delay (milliseconds) +# Delay before running initial decay process to ensure database is ready +# Helps prevent race conditions with SQLite initialization +# Default: 3000 (3 seconds) +OM_DB_INIT_DELAY_MS=3000 + # -------------------------------------------- # Metadata Store # -------------------------------------------- diff --git a/backend/src/core/cfg.ts b/backend/src/core/cfg.ts index 48262127..7604fc19 100644 --- a/backend/src/core/cfg.ts +++ b/backend/src/core/cfg.ts @@ -107,4 +107,5 @@ export const env = { summary_layers: num(process.env.OM_SUMMARY_LAYERS, 3), keyword_boost: num(process.env.OM_KEYWORD_BOOST, 2.5), keyword_min_length: num(process.env.OM_KEYWORD_MIN_LENGTH, 3), + db_init_delay_ms: num(process.env.OM_DB_INIT_DELAY_MS, 3000), }; diff --git a/backend/src/server/index.ts b/backend/src/server/index.ts index bdfb229a..985623ac 100644 --- a/backend/src/server/index.ts +++ b/backend/src/server/index.ts @@ -11,8 +11,8 @@ import { start_reflection } from "../memory/reflect"; import { start_user_summary_reflection } from "../memory/user_summary"; import { sendTelemetry } from "../core/telemetry"; import { req_tracker_mw } from "./routes/dashboard"; - -const ASC = ` ____ __ __ +const ASC = ` + ____ __ __ / __ \\ | \\/ | | | | |_ __ ___ _ __ | \\ / | ___ _ __ ___ ___ _ __ _ _ | | | | '_ \\ / _ \\ '_ \\| |\\/| |/ _ \\ '_ \` _ \\ / _ \\| '__| | | | @@ -21,10 +21,6 @@ const ASC = ` ____ __ __ | | __/ | |_| |___/ `; -// Database initialization delay in milliseconds -// Allows time for SQLite connection to be fully established before running decay -const DB_INIT_DELAY_MS = parseInt(process.env.OM_DB_INIT_DELAY_MS || '3000', 10); - const app = server({ max_payload_size: env.max_payload_size }); console.log(ASC); @@ -117,7 +113,7 @@ setTimeout(async () => { } catch (error) { console.error("[INIT] Initial decay failed:", error); } -}, DB_INIT_DELAY_MS); +}, env.db_init_delay_ms); start_reflection(); start_user_summary_reflection();