FlowiseAI/Flowise · error · Error
Error retrieving ${tableName}
Error message
Error retrieving ${tableName} What it means
Thrown by SQLiteSaver.getTuple() checkpoint_id-present branch when the parameterised SELECT fails. Uses ? placeholder binding. Underlying error logged then re-thrown generically; dataSource.destroy() runs in finally.
Source
Thrown at packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqliteSaver.ts:100
if (rows && rows.length > 0) {
return {
config,
checkpoint: (await this.serde.parse(rows[0].checkpoint)) as Checkpoint,
metadata: (await this.serde.parse(rows[0].metadata)) as CheckpointMetadata,
parentConfig: rows[0].parent_id
? {
configurable: {
thread_id,
checkpoint_id: rows[0].parent_id
}
}
: undefined
}
}
} catch (error) {
console.error(`Error retrieving ${tableName}`, error)
throw new Error(`Error retrieving ${tableName}`)
} finally {
await dataSource.destroy()
}
} else {
try {
const queryRunner = dataSource.createQueryRunner()
const keys = [thread_id]
const sql = `SELECT thread_id, checkpoint_id, parent_id, checkpoint, metadata FROM ${tableName} WHERE thread_id = ? ORDER BY checkpoint_id DESC LIMIT 1`
const rows = await queryRunner.manager.query(sql, [...keys])
await queryRunner.release()
if (rows && rows.length > 0) {
return {
config: {
configurable: {
thread_id: rows[0].thread_id,
checkpoint_id: rows[0].checkpoint_idView on GitHub (pinned to abe4a8601a)
Solutions
- Inspect console.error for the actual SQLite error code and act on it.
- Pre-create or migrate the checkpoints table to match the current DDL (BLOB columns).
- Ensure thread_id and checkpoint_id are strings.
- Resolve file locking (WAL mode, single-writer discipline).
- Maintainer: rethrow with cause.
Example fix
// before
} catch (error) {
console.error(`Error retrieving ${tableName}`, error)
throw new Error(`Error retrieving ${tableName}`)
}
// after
} catch (error) {
throw new Error(`Error retrieving ${tableName}: ${(error as Error).message}`, { cause: error })
} Defensive patterns
Strategy: try-catch
Validate before calling
function buildGetTupleConfig(threadId: string, checkpointId?: string) {
if (!threadId || typeof threadId !== 'string') throw new Error('thread_id must be a non-empty string')
if (checkpointId !== undefined && (typeof checkpointId !== 'string' || !checkpointId)) {
throw new Error('checkpoint_id must be a non-empty string when provided')
}
return { configurable: { thread_id: threadId, ...(checkpointId ? { checkpoint_id: checkpointId } : {}) } }
} Type guard
function isSqliteRetrieveError(e: unknown): boolean {
return e instanceof Error && /^Error retrieving .+$/.test(e.message)
} Try / catch
try {
const tuple = await sqliteSaver.getTuple(config)
} catch (e) {
if (e instanceof Error && /Error retrieving/.test(e.message)) {
// inspect server log; verify table exists, WAL/busy settings, schema freshness
}
throw e
} Prevention
- Keep the SQLite schema migrated after upgrades.
- Use WAL mode and a healthy busy_timeout to reduce read-lock failures.
- Surface server logs for the underlying SQLite error code.
When it happens
Trigger: Calling getTuple with checkpoint_id set while the table is missing, columns drift, the file is locked at read, or the binding parameters are wrong types.
Common situations: Schema drift after Flowise upgrade. SQLite file locked by a long-running writer. Wrong tableName. Empty/undefined thread_id passed through.
Related errors
- Error retrieving ${tableName}
- Error listing ${tableName}
- Error saving checkpoint
- Error listing ${tableName}
- Error saving checkpoint
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/2a504ce5d1e95973.
Report an issue: GitHub.