n8n-io/n8n · error
Supabase delete failed: ${error.message}
Error message
Supabase delete failed: ${error.message} What it means
Thrown by SupabaseVectorStore.delete when the PostgREST delete call returns a non-null error. Root causes, named in the appended message, are usually RLS denying DELETE, a missing table, an auth/connection failure, or (rarely) a constraint that blocks the delete. Empty id lists short-circuit before this call, so this only fires for a real delete attempt.
Source
Thrown at packages/@n8n/agents/src/vector-stores/supabase.ts:149
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) {
const { createClient } = await import('@supabase/supabase-js');
this.client = createClient(this.constructorOptions.url, this.constructorOptions.apiKey);
}
return this.client;
}
}
function toQueryResult(row: SupabaseMatchRow): VectorQueryResult {
return {
id: String(row.id),View on GitHub (pinned to 5ac6606e81)
Solutions
- Inspect the appended message to classify (RLS vs missing relation vs constraint).
- For RLS, use the service role key for trusted deletes or add a DELETE policy.
- Confirm the table name is correct and the table exists.
- For FK/constraint blocks, delete dependent rows first or adjust the constraint.
- Retry transient/network errors.
Example fix
// before — anon key, RLS blocks delete
new SupabaseVectorStore('docs', {
url, apiKey: process.env.SUPABASE_ANON_KEY, tableName: 'docs',
});
// after — service role key, or add a DELETE policy
new SupabaseVectorStore('docs', {
url, apiKey: process.env.SUPABASE_SERVICE_ROLE_KEY, tableName: 'docs',
}); Defensive patterns
Strategy: retry
Validate before calling
function assertSupabaseDeletable(opts: { url: string; apiKey: string; tableName: string }): void {
if (!opts.apiKey) throw new Error('Supabase apiKey missing (service role needed for deletes)');
if (!opts.tableName) throw new Error('Supabase tableName missing');
if (!/^https?:\/\/.+/.test(opts.url)) throw new Error('Supabase url missing/invalid');
}
assertSupabaseDeletable(opts); Try / catch
async function deleteWithRetry(store: SupabaseVectorStore, ids: string[], attempts = 3) {
if (ids.length === 0) return;
for (let i = 0; i < attempts; i++) {
try {
await store.deleteDocuments(ids);
return;
} catch (err) {
const msg = err instanceof Error ? err.message : '';
const transient = /network|timeout|fetch|ECONN|503|504|paused/i.test(msg);
if (!transient || i === attempts - 1) throw err;
await new Promise((r) => setTimeout(r, 2 ** i * 200));
}
}
} Prevention
- Use the service role key for deletes (RLS typically blocks anon-role DELETE).
- Add a DELETE RLS policy if you must use a non-service role.
- Confirm the table exists and has no ON DELETE RESTRICT FKs blocking removal.
- Retry only transient/network errors; escalate RLS/constraint errors immediately.
When it happens
Trigger: RLS policy without a DELETE grant for the api key's role; tableName pointing at a non-existent table; service key wrong/expired; Supabase project paused; foreign-key ON DELETE RESTRICT blocking removal (surfaced through PostgREST).
Common situations: Anon key used for deletes (RLS blocks); RLS enabled but no DELETE policy; schema migration renaming the table; FK constraint preventing deletion of referenced rows.
Related errors
- Supabase upsert failed: ${error.message}
- Supabase query 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/5b93f8dd6471d424.
Report an issue: GitHub.