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

  1. Read the appended message — it distinguishes 'function does not exist' from 'dimensions don't match' from RLS errors.
  2. Create the RPC function exactly as in the store's JSDoc (parameter `query_embedding vector(n)`, returns id/content/metadata/similarity).
  3. Ensure the embedding model dimension matches the table's vector(n); re-create the column if you changed models.
  4. Confirm queryName (if overridden) matches the function name in the database.
  5. 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

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


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/0a5504eb664e0c7b. Report an issue: GitHub.