FlowiseAI/Flowise · error · Error
Error saving checkpoint
Error message
Error saving checkpoint
What it means
Thrown by PostgresSaver.put() when the INSERT ... ON CONFLICT upsert into the checkpoints table fails. The original error is console.error-logged and re-thrown generically. dataSource.destroy() always runs in finally after the queryRunner is released.
Source
Thrown at packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts:229
const row = [
config.configurable?.thread_id || this.threadId,
checkpoint.id,
config.configurable?.checkpoint_id,
Buffer.from(this.serde.stringify(checkpoint)), // Encode to binary
Buffer.from(this.serde.stringify(metadata)) // Encode to binary
]
const tableName = this.sanitizeTableName(this.tableName)
const query = `INSERT INTO ${tableName} (thread_id, checkpoint_id, parent_id, checkpoint, metadata)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (thread_id, checkpoint_id)
DO UPDATE SET checkpoint = EXCLUDED.checkpoint, metadata = EXCLUDED.metadata`
await queryRunner.manager.query(query, row)
await queryRunner.release()
} catch (error) {
console.error('Error saving checkpoint', error)
throw new Error('Error saving checkpoint')
} finally {
await dataSource.destroy()
}
return {
configurable: {
thread_id: config.configurable?.thread_id || this.threadId,
checkpoint_id: checkpoint.id
}
}
}
async delete(threadId: string): Promise<void> {
if (!threadId) {
return
}
const dataSource = await this.getDataSource()View on GitHub (pinned to abe4a8601a)
Solutions
- Read the console.error to get the underlying Postgres SQLSTATE (e.g. 42804 wrong datatype, 23505/unique violation handled by ON CONFLICT so unlikely, 57014 statement timeout) and act on it.
- Ensure the checkpoints table matches the DDL (checkpoint BYTEA, metadata BYTEA).
- Reduce checkpoint payload size or raise statement_timeout if you hit timeouts.
- Verify the role has INSERT and UPDATE privileges.
- Maintainer: rethrow with cause.
Example fix
// before
} catch (error) {
console.error('Error saving checkpoint', error)
throw new Error('Error saving checkpoint')
}
// after
} catch (error) {
throw new Error(`Error saving checkpoint: ${(error as Error).message}`, { cause: error })
} Defensive patterns
Strategy: try-catch
Validate before calling
function assertCheckpointWritable(checkpoint: { id?: unknown }, config: { configurable?: { checkpoint_id?: unknown } }) {
if (!config.configurable?.checkpoint_id) throw new Error('put() requires config.configurable.checkpoint_id')
if (typeof checkpoint.id !== 'string' || !checkpoint.id) throw new Error('checkpoint.id must be a non-empty string')
} Type guard
function isPutSaveError(e: unknown): boolean {
return e instanceof Error && e.message === 'Error saving checkpoint'
} Try / catch
try {
await saver.put(config, checkpoint, metadata)
} catch (e) {
if (e instanceof Error && e.message === 'Error saving checkpoint') {
// check log for SQLSTATE; verify BYTEA columns, payload size, role privileges
}
throw e
} Prevention
- Migrate the checkpoints table after Flowise upgrades to keep BYTEA columns aligned.
- Trim oversized checkpoints before serialization to avoid statement timeouts.
- Confirm role has INSERT/UPDATE privileges.
When it happens
Trigger: Calling put(config, checkpoint, metadata) without a checkpoint_id returns {} early; otherwise the upsert runs and can fail on missing table, column mismatch, BYTEA encoding issues, oversized payload, or connection loss.
Common situations: Schema drift where checkpoint/metadata columns are not BYTEA. Very large checkpoints exceeding Postgres field size or statement_timeout. Connection drop. Permissions on INSERT/UPDATE.
Related errors
- Error saving checkpoint
- Error retrieving ${tableName}
- Error creating ${this.tableName} table
- Error listing ${tableName}
- Error retrieving ${tableName}
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/9a525e5ebf48f318.
Report an issue: GitHub.