{"record":{"id":"bb0700cc440bbd3b","repo":"FlowiseAI/Flowise","slug":"error-creating-this-tablename-table-bb0700","errorCode":null,"errorMessage":"Error creating ${this.tableName} table","messagePattern":"Error creating (.+?) table","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts","lineNumber":67,"sourceCode":"        if (this.isSetup) {\n            return\n        }\n\n        try {\n            const queryRunner = dataSource.createQueryRunner()\n            const tableName = this.sanitizeTableName(this.tableName)\n            await queryRunner.manager.query(`\nCREATE TABLE IF NOT EXISTS ${tableName} (\n    thread_id TEXT NOT NULL,\n    checkpoint_id TEXT NOT NULL,\n    parent_id TEXT,\n    checkpoint BYTEA,\n    metadata BYTEA,\n    PRIMARY KEY (thread_id, checkpoint_id));`)\n            await queryRunner.release()\n        } catch (error) {\n            console.error(`Error creating ${this.tableName} table`, error)\n            throw new Error(`Error creating ${this.tableName} table`)\n        }\n\n        this.isSetup = true\n    }\n\n    async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n        const dataSource = await this.getDataSource()\n        await this.setup(dataSource)\n\n        const thread_id = config.configurable?.thread_id || this.threadId\n        const checkpoint_id = config.configurable?.checkpoint_id\n        const tableName = this.sanitizeTableName(this.tableName)\n\n        if (checkpoint_id) {\n            try {\n                const queryRunner = dataSource.createQueryRunner()\n                const keys = [thread_id, checkpoint_id]\n                const sql = `SELECT checkpoint, parent_id, metadata FROM ${tableName} WHERE thread_id = $1 AND checkpoint_id = $2`","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts#L49-L85","documentation":"Thrown by PostgresSaver.setup() when the CREATE TABLE IF NOT EXISTS DDL for the checkpoints table fails. The original TypeORM/Postgres error is logged via console.error but re-thrown as an opaque generic Error, hiding the underlying cause. This runs once per saver instance (guarded by isSetup) on the first getTuple/list/put call.","triggerScenarios":"First checkpoint operation after constructing PostgresSaver when: the Postgres user lacks CREATE permission, the database/connection is wrong, the tableName contains characters rejected by Postgres after sanitizeTableName (sanitize only allows [A-Za-z0-9_]), the schema does not exist, or the connection drops mid-DDL.","commonSituations":"Restricted DB role provisioned without DDL privileges. Misconfigured host/credentials that still connect but to the wrong database. Reserved Postgres table names that pass the regex but collide with system catalogs. Concurrent savers racing on the same table on a connection that times out.","solutions":["Inspect the server/terminal log immediately before this error — console.error prints the real cause; fix that root cause (permissions, missing DB, bad tableName).","Grant CREATE (or make the table owner pre-create it) to the connecting role, or pre-create the checkpoints table so CREATE TABLE IF NOT EXISTS is a no-op.","Confirm datasourceOptions.host/database/username are correct by connecting with psql using the same credentials.","Ensure this.tableName passes sanitizeTableName and is not a Postgres reserved word; if customization is needed, rename it.","If you maintain this code, wrap and rethrow with `cause` so callers see the underlying error instead of the generic message."],"exampleFix":"// before\n} catch (error) {\n    console.error(`Error creating ${this.tableName} table`, error)\n    throw new Error(`Error creating ${this.tableName} table`)\n}\n// after\n} catch (error) {\n    throw new Error(`Error creating ${this.tableName} table: ${(error as Error).message}`, { cause: error })\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight: verify role can create the table, or that it already exists.\nimport { DataSource } from 'typeorm'\nasync function ensureCheckpointsTable(ds: DataSource, tableName: string): Promise<void> {\n  const exists = await ds.query(\n    `SELECT to_regclass($1) IS NOT NULL AS exists`,\n    [`public.${tableName}`]\n  )\n  if (!exists[0]?.exists) {\n    // attempt create with explicit privileges; throw a typed error if it fails\n    await ds.query(`CREATE TABLE IF NOT EXISTS ${tableName} (...)`)\n  }\n}","typeGuard":"function isSetupError(e: unknown, tableName: string): boolean {\n  return e instanceof Error && e.message === `Error creating ${tableName} table`\n}","tryCatchPattern":"try {\n  await saver.getTuple(config)\n} catch (e) {\n  if (e instanceof Error && /Error creating .* table/.test(e.message)) {\n    // inspect server logs for the real cause; check role grants and pre-create the table\n  }\n  throw e\n}","preventionTips":["Pre-create the checkpoints table via a migration so runtime CREATE is a no-op.","Provision the DB role with CREATE on the target schema, or make it the table owner.","Keep an eye on server logs — the real cause is console.error'd before the rethrow.","If you maintain the saver, rethrow with cause to avoid this diagnostic black hole."],"tags":["postgres","ddl","permissions","setup","error-masking"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}