ToolJet/ToolJet · error · QueryBuilderError

A column entry has a value but no column name specified

Error message

A column entry has a value but no column name specified

What it means

Thrown by createRow when a columns entry carries a value but its column name is blank or whitespace. The builder needs a column name to quote into the INSERT column list; a value without a target column is rejected. Fully-empty entries (no column and empty value) are silently skipped, and if all are empty it falls back to INSERT ... DEFAULT VALUES.

Source

Thrown at plugins/packages/common/lib/queryBuilder.ts:398

    return parts.length > 0 ? parts.join(', ') : '*';
  }

  // ── Operations ──────────────────────────────────────────────────────────────
  createRow(
    tableName: string,
    schema: string | undefined | null,
    columns: Record<string, CreateRowEntry> | undefined | null
  ): QueryResult {
    this._reset();
    this._assertTableName(tableName, 'create_row');

    const table = this._buildTableRef(tableName, schema);

    const entries = Object.values(columns || {}).filter((entry) => {
      const hasColumn = !!(entry.column && String(entry.column).trim());
      const isValueEmpty = entry.value === undefined || entry.value === null || entry.value === '';
      if (!hasColumn && isValueEmpty) return false; // skip if both key and value is empty
      if (!hasColumn) throw new QueryBuilderError('A column entry has a value but no column name specified'); // Throw error if column name is missing but value is provided
      return true;
    });

    // If no valid columns are provided, generate an INSERT with DEFAULT VALUES
    if (entries.length === 0) {
      const query = `INSERT INTO ${table} DEFAULT VALUES`;
      return { query, params: [] };
    }

    const cols = entries.map((e) => this._dialect.quote(e.column));
    const placeholders = entries.map((e) => this._addParam(e.value));

    const query = `INSERT INTO ${table} (${cols.join(', ')}) VALUES (${placeholders.join(', ')})`;
    return { query, params: [...this._params] };
  }

  updateRows(tableName: string, updateRows: UpdateRowsInput): QueryResult {
    this._reset();

View on GitHub (pinned to 20602a8e10)

Solutions

  1. Ensure each columns entry with a value also has a non-empty column.
  2. Drop fully-empty rows before calling createRow; if all are empty, DEFAULT VALUES is used automatically.
  3. Build the columns map from a concrete column list, not free-form input.

Example fix

// before
columns: { c1: { column: '', value: 'alice' } }
// after
columns: { c1: { column: 'name', value: 'alice' } }
Defensive patterns

Strategy: validation

Validate before calling

function cleanCreateColumns(columns = {}) {
  const out = {};
  for (const [k, e] of Object.entries(columns)) {
    const col = (e.column ?? '').toString().trim();
    const empty = e.value === undefined || e.value === null || e.value === '';
    if (!col && empty) continue; // fully empty -> skip
    if (!col) continue;           // value without column -> drop (or surface error)
    out[k] = { ...e, column: col };
  }
  return out;
}
// usage: qb.createRow('users', 'public', cleanCreateColumns(input.columns))

Type guard

function isCompleteCreateEntry(e: { column?: string; value?: unknown }): boolean {
  const hasCol = !!(e.column && String(e.column).trim());
  const empty = e.value === undefined || e.value === null || e.value === '';
  return hasCol || empty; // valid if column set, or fully empty (auto-skipped)
}

Try / catch

try {
  qb.createRow('users', 'public', columns);
} catch (e) {
  if (e instanceof QueryBuilderError && /no column name specified/.test(e.message)) {
    return { error: 'Each value needs a target column.' };
  }
  throw e;
}

Prevention

When it happens

Trigger: qb.createRow('users', 'public', { c1: { column: '', value: 'alice' } }), { column: ' ', value: 42 }, or a columns map built from a form row whose column key was cleared.

Common situations: An editable grid where a cell value was typed but the row's column selector is empty; serializing form state that includes a value but lost its column binding; copying a template row and not setting the column.

Related errors


AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13). Data as JSON: /api/errors/afbc9ac5abc0f1b6. Report an issue: GitHub.