n8n-io/n8n · error
Invalid PgVectorStore table name "${String(this.tableName)}"
Error message
Invalid PgVectorStore table name "${String(this.tableName)}": must match ${IDENTIFIER_PATTERN} What it means
Thrown in the PgVectorStore constructor when tableName fails the IDENTIFIER_PATTERN `/^[A-Za-z_][A-Za-z0-9_]*$/`. The table name is interpolated directly into SQL (it cannot be a bind parameter), so it is locked to a safe identifier grammar to prevent SQL injection and syntax errors. Schema-qualified names, dots, hyphens, spaces, digits-first, and quoted identifiers all fail. This throws at construction time, before any DB connection.
Source
Thrown at packages/@n8n/agents/src/vector-stores/postgres.ts:58
* ```typescript
* const store = new PgVectorStore('product-docs', {
* connectionString: 'postgresql://user:pass@localhost:5432/db',
* tableName: 'product_docs',
* });
* ```
*/
export class PgVectorStore extends BaseVectorStore<PgVectorStoreOptions> {
private readonly tableName: string;
private pool?: Pool;
private iterativeScanSupportedPromise?: Promise<boolean>;
constructor(name: string, options: PgVectorStoreOptions) {
super(name, options);
this.tableName = options.tableName;
if (typeof this.tableName !== 'string' || !IDENTIFIER_PATTERN.test(this.tableName)) {
throw new Error(
`Invalid PgVectorStore table name "${String(this.tableName)}": must match ${IDENTIFIER_PATTERN}`,
);
}
}
async upsert(records: VectorRecord[]): Promise<void> {
if (records.length === 0) return;
const pool = await this.getPool();
const values: string[] = [];
const params: unknown[] = [];
records.forEach((record, index) => {
const base = index * 4;
values.push(`($${base + 1}, $${base + 2}, $${base + 3}, $${base + 4}::vector)`);
params.push(
record.id,
record.content,
JSON.stringify(record.metadata),View on GitHub (pinned to 5ac6606e81)
Solutions
- Pass a bare identifier matching the pattern: letters/underscore start, then letters/digits/underscore (e.g. `product_docs`).
- If your table is in a non-public schema, connect with a role/search_path that defaults to that schema and pass only the table name.
- Rename the Postgres table to a valid identifier if you control the schema.
- Validate the table name from config with the same regex before constructing the store.
Example fix
// before
new PgVectorStore('docs', { connectionString, tableName: 'public.product-docs' });
// after
new PgVectorStore('docs', { connectionString, tableName: 'product_docs' }); Defensive patterns
Strategy: validation
Validate before calling
const IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
function assertValidTableName(name: unknown): string {
if (typeof name !== 'string' || !IDENTIFIER_PATTERN.test(name)) {
throw new Error(`Invalid table name "${String(name)}": must match ${IDENTIFIER_PATTERN}`);
}
return name;
}
new PgVectorStore('docs', { connectionString, tableName: assertValidTableName(process.env.PG_TABLE) }); Type guard
function isValidPgIdentifier(name: string): boolean {
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
}
if (!isValidPgIdentifier(config.table)) throw new Error('Bad table name'); Prevention
- Keep Postgres table names as bare identifiers: letters/underscore start, then letters/digits/underscore.
- Don't schema-qualify at the store layer — set the role/search_path instead.
- Validate config-provided table names with the same regex before constructing the store.
When it happens
Trigger: Passing `tableName: 'public.product_docs'` (dot), `'product-docs'` (hyphen), `'2docs'` (digit-first), `'Product Docs'` (space/uppercase+space — uppercase alone is allowed but space is not), `'"docs"'` (quotes), or an empty string.
Common situations: Using a schema-qualified Postgres table name; copying a table name with hyphens from a separate DB tool; environment/config injection of an unvalidated table name; multi-tenant setups wanting `tenant_123.docs`.
Related errors
- Model ID is required
- Invalid delegate sub-agent tool name "${name}": must start w
- ${toolName} requires resumeSubAgent and cancelSubAgent to be
- toolCallConcurrency must be a positive integer or Infinity
- Tool name is required
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/0530474589f13a5e.
Report an issue: GitHub.