n8n-io/n8n · error
Supabase query failed: ${error.message}
Error message
Supabase query failed: ${error.message} What it means
Thrown by SupabaseVectorStore.query when the PostgREST RPC call (to match_documents by default, or queryName) returns a non-null error. Common root causes exposed in the appended message: the RPC function does not exist, the vector dimension does not match the column's vector(n), wrong queryName, RLS blocking SELECT, or a connection/auth failure. Runtime/backend error, not local validation.
Source
Thrown at packages/@n8n/agents/src/vector-stores/supabase.ts:139
);
if (error) throw new Error(`Supabase upsert failed: ${error.message}`);
}
async query(
vector: number[],
opts: { topK: number; filter?: VectorFilter },
): Promise<VectorQueryResult[]> {
const client = await this.getClient();
const rpcCall = client.rpc<string, MatchDocumentsFn>(this.queryName, {
query_embedding: vector,
});
const filtered =
opts.filter && opts.filter.conditions.length > 0
? applySupabaseFilter(rpcCall, opts.filter)
: rpcCall;
const { data, error } = await filtered.limit(opts.topK);
if (error) throw new Error(`Supabase query failed: ${error.message}`);
return (data ?? []).map(toQueryResult);
}
async delete({ ids }: { ids: string[] }): Promise<void> {
if (ids.length === 0) return;
const client = await this.getClient();
const { error } = await client.from(this.tableName).delete().in('id', ids);
if (error) throw new Error(`Supabase delete failed: ${error.message}`);
}
close(): void {
this.client = undefined;
}
private async getClient(): Promise<SupabaseClient> {
if (!this.client) {View on GitHub (pinned to 5ac6606e81)
Solutions
- Read the appended message — it distinguishes 'function does not exist' from 'dimensions don't match' from RLS errors.
- Create the RPC function exactly as in the store's JSDoc (parameter `query_embedding vector(n)`, returns id/content/metadata/similarity).
- Ensure the embedding model dimension matches the table's vector(n); re-create the column if you changed models.
- Confirm queryName (if overridden) matches the function name in the database.
- For transient failures, retry.
Example fix
// before — default RPC missing / dimension mismatch
const store = new SupabaseVectorStore('docs', { url, apiKey, tableName: 'docs' });
// embedding model changed to 1536-dim but column is vector(384)
// after — recreate column and RPC at the right dimension
/*
ALTER TABLE docs ALTER COLUMN embedding TYPE vector(1536);
DROP FUNCTION match_documents;
CREATE FUNCTION match_documents(query_embedding vector(1536))
RETURNS TABLE (id text, content text, metadata jsonb, similarity float)
LANGUAGE sql STABLE AS $$
SELECT id, content, metadata, 1 - (embedding <=> query_embedding) AS similarity
FROM docs ORDER BY embedding <=> query_embedding;
$$;
*/ Defensive patterns
Strategy: try-catch
Validate before calling
function assertSupabaseQueryConfig(opts: { url: string; apiKey: string; tableName: string; queryName?: string }): void {
if (!/^https?:\/\/.+/.test(opts.url)) throw new Error('Supabase url missing/invalid');
if (!opts.apiKey) throw new Error('Supabase apiKey missing');
if (!opts.tableName) throw new Error('Supabase tableName missing');
if (opts.queryName && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(opts.queryName)) {
throw new Error(`Invalid RPC name "${opts.queryName}"`);
}
}
assertSupabaseQueryConfig(opts); Try / catch
try {
await store.search(query);
} catch (err) {
const msg = err instanceof Error ? err.message : '';
if (/Could not find the function/.test(msg)) {
throw new Error('match_documents RPC missing — create it per the store docs');
}
if (/different.*dimension|dimensions don't match/i.test(msg)) {
throw new Error('Embedding dimension mismatch — re-create the vector column');
}
const transient = /network|timeout|fetch|ECONN|503|504|paused/i.test(msg);
if (transient) { /* retry with backoff */ } else throw err;
} Prevention
- Create the match_documents RPC exactly as documented, with vector(n) matching your embedding model.
- When changing embedding models, re-create the vector column and the RPC at the new dimension.
- If you override queryName, ensure it matches a real PostgREST function name.
- Retry only transient errors; classify 'function not found' / 'dimension mismatch' as configuration fixes.
When it happens
Trigger: Default RPC `match_documents` not defined in the database; queryName customized to a function that doesn't exist; embedding model changed to a different dimension than the table's vector(n) column; RLS denying select on the table; Supabase unreachable/auth expired; passing a vector of the wrong length.
Common situations: Switching embedding models without re-creating the vector column at the new dimension; forgetting to run the match_documents SQL from the store docs; custom queryName typo; RLS on the table blocking the query role.
Related errors
- Supabase upsert failed: ${error.message}
- Supabase delete failed: ${error.message}
- Filter operator "${operator}" on key "${key}" requires a non
- Database connection timed out
- Error: ${errorMessage}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/0a5504eb664e0c7b.
Report an issue: GitHub.