fix(session-sync): handle missing estimated_cost_usd column in old Hermes state.db (#312)
* fix(session-sync): handle missing estimated_cost_usd column in old Hermes state.db Fixes #308 - "NOT NULL constraint failed: sessions.estimated_cost_usd" Problem: - Old versions of Hermes state.db don't have the estimated_cost_usd column - Session sync would fail when trying to query this column - New sessions also failed to sync because the error blocked the entire sync process Solution: - Dynamically detect if estimated_cost_usd column exists using PRAGMA table_info - For old DBs (no column): return 0 as hardcoded default value - For new DBs (has column): use COALESCE(estimated_cost_usd, 0) to handle NULL values - This ensures backward compatibility with both old and new Hermes installations Changes: - Add PRAGMA table_info check before building SELECT query - Conditionally include estimated_cost_usd column based on schema detection - Ensures session sync works for both old and new Hermes state.db versions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: correct type annotation for PRAGMA table_info result - Change from Array<{ name: string }>[] to Array<{ name: string }> - Fixes TypeScript compilation error - PRAGMA table_info returns an array of objects, not an array of arrays Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,6 +112,13 @@ function syncProfileSessions(profile: string): {
|
||||
const db = openHermesStateDb(profile)
|
||||
|
||||
try {
|
||||
// Check if sessions table has estimated_cost_usd column
|
||||
const tableInfo = db.prepare('PRAGMA table_info(sessions)').all() as Array<{ name: string }>
|
||||
const hasEstimatedCost = tableInfo.some(col => col.name === 'estimated_cost_usd')
|
||||
|
||||
// Build SELECT query - only include estimated_cost_usd if column exists
|
||||
const estimatedCostCol = hasEstimatedCost ? ', COALESCE(estimated_cost_usd, 0) AS estimated_cost_usd' : ', 0 AS estimated_cost_usd'
|
||||
|
||||
// Get all api_server sessions
|
||||
const sessions = db.prepare(`
|
||||
SELECT
|
||||
@@ -128,8 +135,7 @@ function syncProfileSessions(profile: string): {
|
||||
output_tokens,
|
||||
cache_read_tokens,
|
||||
cache_write_tokens,
|
||||
reasoning_tokens,
|
||||
estimated_cost_usd
|
||||
reasoning_tokens${estimatedCostCol}
|
||||
FROM sessions
|
||||
WHERE source = 'api_server'
|
||||
ORDER BY started_at ASC
|
||||
@@ -218,7 +224,7 @@ function syncProfileSessions(profile: string): {
|
||||
cache_read_tokens: hermesSession.cache_read_tokens,
|
||||
cache_write_tokens: hermesSession.cache_write_tokens,
|
||||
reasoning_tokens: hermesSession.reasoning_tokens,
|
||||
estimated_cost_usd: hermesSession.estimated_cost_usd,
|
||||
estimated_cost_usd: hermesSession.estimated_cost_usd || 0,
|
||||
last_active: hermesSession.started_at, // Use started_at as fallback since last_active doesn't exist in Hermes state.db
|
||||
preview,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user