{"record":{"id":"9a525e5ebf48f318","repo":"FlowiseAI/Flowise","slug":"error-saving-checkpoint-9a525e","errorCode":null,"errorMessage":"Error saving checkpoint","messagePattern":"Error saving checkpoint","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts","lineNumber":229,"sourceCode":"            const row = [\n                config.configurable?.thread_id || this.threadId,\n                checkpoint.id,\n                config.configurable?.checkpoint_id,\n                Buffer.from(this.serde.stringify(checkpoint)), // Encode to binary\n                Buffer.from(this.serde.stringify(metadata)) // Encode to binary\n            ]\n            const tableName = this.sanitizeTableName(this.tableName)\n\n            const query = `INSERT INTO ${tableName} (thread_id, checkpoint_id, parent_id, checkpoint, metadata)\n                           VALUES ($1, $2, $3, $4, $5)\n                           ON CONFLICT (thread_id, checkpoint_id)\n                           DO UPDATE SET checkpoint = EXCLUDED.checkpoint, metadata = EXCLUDED.metadata`\n\n            await queryRunner.manager.query(query, row)\n            await queryRunner.release()\n        } catch (error) {\n            console.error('Error saving checkpoint', error)\n            throw new Error('Error saving checkpoint')\n        } finally {\n            await dataSource.destroy()\n        }\n\n        return {\n            configurable: {\n                thread_id: config.configurable?.thread_id || this.threadId,\n                checkpoint_id: checkpoint.id\n            }\n        }\n    }\n\n    async delete(threadId: string): Promise<void> {\n        if (!threadId) {\n            return\n        }\n\n        const dataSource = await this.getDataSource()","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts#L211-L247","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n} catch (error) {\n    console.error('Error saving checkpoint', error)\n    throw new Error('Error saving checkpoint')\n}\n// after\n} catch (error) {\n    throw new Error(`Error saving checkpoint: ${(error as Error).message}`, { cause: error })\n}","handlingStrategy":"try-catch","validationCode":"function assertCheckpointWritable(checkpoint: { id?: unknown }, config: { configurable?: { checkpoint_id?: unknown } }) {\n  if (!config.configurable?.checkpoint_id) throw new Error('put() requires config.configurable.checkpoint_id')\n  if (typeof checkpoint.id !== 'string' || !checkpoint.id) throw new Error('checkpoint.id must be a non-empty string')\n}","typeGuard":"function isPutSaveError(e: unknown): boolean {\n  return e instanceof Error && e.message === 'Error saving checkpoint'\n}","tryCatchPattern":"try {\n  await saver.put(config, checkpoint, metadata)\n} catch (e) {\n  if (e instanceof Error && e.message === 'Error saving checkpoint') {\n    // check log for SQLSTATE; verify BYTEA columns, payload size, role privileges\n  }\n  throw e\n}","preventionTips":["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."],"tags":["postgres","write","upsert","error-masking","schema-drift"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}