vitessio/vitess · error

VT03014

VT03014

Error message

unknown column '%s' in '%s'

What it means

Inside ON DUPLICATE KEY UPDATE, VALUES(col) references a column that is not present in the INSERT's column list. When Vitess rewrites VALUES(...) expressions to the actual row values, FindColumn returns -1 and it panics with VT03014 ('unknown column ... in field list').

Source

Thrown at go/vt/vtgate/planbuilder/operators/upsert.go:116

				expr = pIdx.def
			} else {
				expr = row[pIdx.idx]
			}
			comparisons = append(comparisons,
				sqlparser.NewComparisonExpr(sqlparser.EqualOp, sqlparser.NewColName(pIdx.col.String()), expr, nil))
		}
		whereExpr := sqlparser.AndExpressions(comparisons...)

		var updExprs sqlparser.UpdateExprs
		for _, ue := range ins.OnDup {
			expr := sqlparser.CopyOnRewrite(ue.Expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) {
				vfExpr, ok := cursor.Node().(*sqlparser.ValuesFuncExpr)
				if !ok {
					return
				}
				idx := ins.Columns.FindColumn(vfExpr.Name.Name)
				if idx == -1 {
					panic(vterrors.VT03014(sqlparser.String(vfExpr.Name), "field list"))
				}
				cursor.Replace(row[idx])
			}, nil).(sqlparser.Expr)
			updExprs = append(updExprs, &sqlparser.UpdateExpr{
				Name: ue.Name,
				Expr: expr,
			})
		}

		upd := &sqlparser.Update{
			Comments:   ins.Comments,
			TableExprs: sqlparser.TableExprs{ins.Table},
			Exprs:      updExprs,
			Where:      sqlparser.NewWhere(sqlparser.WhereClause, whereExpr),
		}
		updOp := createOpFromStmt(ctx, upd, false, "")

		// replan insert statement without on duplicate key update.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Add the missing column to the INSERT's column list so VALUES(col) can resolve
  2. Fix the column name typo inside VALUES(...)
  3. Only reference columns actually listed in the INSERT statement

Example fix

// before
INSERT INTO t (a) VALUES (1) ON DUPLICATE KEY UPDATE b = VALUES(b);
// after
INSERT INTO t (a, b) VALUES (1, 2) ON DUPLICATE KEY UPDATE b = VALUES(b);
Defensive patterns

Strategy: validation

Validate before calling

// validate VALUES() references against the INSERT column list
cols := map[string]bool{"a": true, "b": true} // ins.Columns
for _, ref := range valuesFuncRefs {
    if !cols[ref] {
        return fmt.Errorf("unknown column %q in field list", ref)
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unknown column") && strings.Contains(err.Error(), "field list") {
    // fix statement: add missing column to INSERT list
}

Prevention

When it happens

Trigger: createUpsertOperator's CopyOnRewrite callback encounters a ValuesFuncExpr whose column name is not found in ins.Columns while expanding each values row.

Common situations: Typo in VALUES(col) name; column exists in the table but was omitted from the INSERT column list; dynamically generated upserts referencing the wrong column.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/bffef2dac1b4913b. Report an issue: GitHub.