ToolJet/ToolJet · warning · Error
Duplicate column keys are not allowed
Error message
Duplicate column keys are not allowed
What it means
Thrown by Supabase plugin updateRows() when two column-field entries target the same column name. The duplicate check `columnNames.some((item, idx) => columnNames.indexOf(item) != idx)` detects any repeated name and throws 'Duplicate column keys are not allowed' before building the update payload, because the later value would silently overwrite the earlier one.
Source
Thrown at marketplace/plugins/supabase/lib/index.ts:128
const { create_table_name, create_body } = queryOptions;
if (!create_body) throw new Error('Body required to create rows in table');
const res = await supabaseClient.from(create_table_name).insert(JSON.parse(create_body));
return res;
}
async updateRows(queryOptions: QueryOptions, supabaseClient: SupabaseClientType): Promise<Response> {
const { update_table_name, update_filters, update_column_fields } = queryOptions;
if (!update_column_fields) throw new Error('No column(s) provided to update');
const updateColumnValues: Column[] = Object.values(update_column_fields);
if (!updateColumnValues.length) throw new Error('No column(s) provided to update');
const columnNames: string[] = updateColumnValues.map((item) => item.column).filter((columnName) => !!columnName);
if (!columnNames.length) throw new Error('Provide column(s) with valid data');
const isDuplicate: boolean = columnNames.some((item, idx) => columnNames.indexOf(item) != idx);
if (isDuplicate) {
throw new Error('Duplicate column keys are not allowed');
}
const updateQuery = supabaseClient.from(update_table_name).select();
if (update_filters) {
const updateFiltersData: Filter[] = Object.values(update_filters);
this.addQueryFilters(updateQuery, updateFiltersData);
}
const { data, error } = await updateQuery;
if (error) throw new Error('Failed to fetch table rows to update');
const columnsData: object = {};
updateColumnValues.forEach((columnObj) => {
columnsData[columnObj.column] = columnObj.value;
});
const updateQueryRes: object[] = data.map((data: object) => ({ ...data, ...columnsData }));
const res = await supabaseClient.from(update_table_name).upsert(updateQueryRes).select();
return res;
}
View on GitHub (pinned to 20602a8e10)
Solutions
- Remove or merge duplicate column-field entries so each column name appears exactly once.
- Dedupe client-side, keeping the intended value, before calling run().
- When generating entries programmatically, key the object by column name to prevent repeats.
Example fix
// before
update_column_fields: {
c1: { column: 'status', value: 'a' },
c2: { column: 'status', value: 'b' }
}
// after
update_column_fields: { c1: { column: 'status', value: 'b' } } Defensive patterns
Strategy: validation
Validate before calling
function ensureNoDuplicateColumns(qo) {
if (qo.operation !== 'update_row') return;
const names = Object.values(qo.update_column_fields || {}).map(c => c && c.column).filter(Boolean);
const dupe = names.find((n, i) => names.indexOf(n) !== i);
if (dupe) throw new Error(`Duplicate column keys are not allowed: ${dupe}`);
}
ensureNoDuplicateColumns(queryOptions); Type guard
function columnNamesUnique(qo): boolean {
if (qo.operation !== 'update_row') return true;
const names = Object.values(qo.update_column_fields || {}).map(c => c && c.column).filter(Boolean);
return names.every((n, i) => names.indexOf(n) === i);
} Try / catch
try { await svc.run(src, qo, id); } catch (e) { if (/Duplicate column/.test(e.message)) { dedupeColumnFields(); return; } throw e; } Prevention
- Key the update_column_fields object by column name so duplicates are impossible by construction.
- Run a uniqueness check on column names in the UI and block Run on conflict.
- When merging column rows programmatically, last-write-wins to a single entry per column.
When it happens
Trigger: update_column_fields contains two or more entries whose .column is identical, e.g. { c1: { column: 'status', value: 'a' }, c2: { column: 'status', value: 'b' } }.
Common situations: User added the same column twice by mistake; a duplicated control binding produced repeated column names; copy-paste of a column row without changing its target.
Related errors
- No column(s) provided to update
- Provide column(s) with valid data
- Select one operation
- Table name is required
- Body required to create rows in table
AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13).
Data as JSON: /api/errors/2a2f7f9d7e75226a.
Report an issue: GitHub.