{"record":{"id":"e4f7063110a94709","repo":"FlowiseAI/Flowise","slug":"error-retrieving-tablename","errorCode":null,"errorMessage":"Error retrieving ${tableName}","messagePattern":"Error retrieving (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts","lineNumber":107,"sourceCode":"\n                if (rows && rows.length > 0) {\n                    return {\n                        config,\n                        checkpoint: (await this.serde.parse(rows[0].checkpoint.toString())) as Checkpoint,\n                        metadata: (await this.serde.parse(rows[0].metadata.toString())) as CheckpointMetadata,\n                        parentConfig: rows[0].parent_id\n                            ? {\n                                  configurable: {\n                                      thread_id,\n                                      checkpoint_id: rows[0].parent_id\n                                  }\n                              }\n                            : undefined\n                    }\n                }\n            } catch (error) {\n                console.error(`Error retrieving ${tableName}`, error)\n                throw new Error(`Error retrieving ${tableName}`)\n            } finally {\n                await dataSource.destroy()\n            }\n        } else {\n            try {\n                const queryRunner = dataSource.createQueryRunner()\n                const keys = [thread_id]\n                const sql = `SELECT thread_id, checkpoint_id, parent_id, checkpoint, metadata FROM ${tableName} WHERE thread_id = $1 ORDER BY checkpoint_id DESC LIMIT 1`\n\n                const rows = await queryRunner.manager.query(sql, keys)\n                await queryRunner.release()\n\n                if (rows && rows.length > 0) {\n                    return {\n                        config: {\n                            configurable: {\n                                thread_id: rows[0].thread_id,\n                                checkpoint_id: rows[0].checkpoint_id","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts#L89-L125","documentation":"Thrown by PostgresSaver.getTuple() inside the checkpoint_id-present branch when the SELECT-by-checkpoint_id query fails. The underlying error is console.error-logged then re-thrown as an opaque generic message. dataSource.destroy() always runs in finally.","triggerScenarios":"Calling getTuple with config.configurable.checkpoint_id set, while: the table does not exist (setup skipped or failed silently elsewhere), the connection dropped, the column does not match (schema drift after a Flowise upgrade), or a parameter binding/type mismatch occurs.","commonSituations":"Schema drift after upgrading Flowise where the checkpoints table shape changed but the table already existed (so CREATE TABLE IF NOT EXISTS did not migrate it). Network blips to managed Postgres. Wrong tableName between savers sharing a DB.","solutions":["Read the console.error line above the throw for the real Postgres error code (e.g. 42P01 undefined-table, 42703 undefined-column) and act on it.","If the table is missing or has the wrong shape, drop/recreate it or run setup() against a fresh table name so CREATE TABLE applies.","Confirm the checkpoint_id and thread_id passed in config.configurable are strings and non-empty.","Stabilize the connection (pool sizing, SSL config, network) if the underlying error is a socket/timeout.","As a maintainer, rethrow with cause to preserve diagnosability."],"exampleFix":"// before\n} catch (error) {\n    console.error(`Error retrieving ${tableName}`, error)\n    throw new Error(`Error retrieving ${tableName}`)\n}\n// after\n} catch (error) {\n    throw new Error(`Error retrieving ${tableName}: ${(error as Error).message}`, { cause: error })\n}","handlingStrategy":"try-catch","validationCode":"function buildGetTupleConfig(threadId: string, checkpointId?: string) {\n  if (!threadId || typeof threadId !== 'string') throw new Error('thread_id must be a non-empty string')\n  if (checkpointId !== undefined && (typeof checkpointId !== 'string' || !checkpointId)) {\n    throw new Error('checkpoint_id must be a non-empty string when provided')\n  }\n  return { configurable: { thread_id: threadId, ...(checkpointId ? { checkpoint_id: checkpointId } : {}) } }\n}","typeGuard":"function isCheckpointTupleRetrieveError(e: unknown): boolean {\n  return e instanceof Error && /^Error retrieving .+$/.test(e.message)\n}","tryCatchPattern":"try {\n  const tuple = await saver.getTuple(config)\n} catch (e) {\n  if (e instanceof Error && /Error retrieving/.test(e.message)) {\n    // read server log for underlying SQLSTATE; verify table existence and schema\n  }\n  throw e\n}","preventionTips":["Migrate the checkpoints table whenever you upgrade Flowise.","Keep thread_id / checkpoint_id strongly typed as strings at the boundary.","Surface server logs during debugging — opaque messages hide the real cause."],"tags":["postgres","query","read","error-masking","schema-drift"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}