{"record":{"id":"0bbda9f40c25680f","repo":"vitessio/vitess","slug":"errcannotupdateimmutablecolumn","errorCode":"ErrCannotUpdateImmutableColumn","errorMessage":"%w %+v: %v","messagePattern":"%w %\\+v: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/vexec/query_planner.go","lineNumber":224,"sourceCode":"\t}, nil\n}\n\nfunc (planner *VReplicationQueryPlanner) planUpdate(upd *sqlparser.Update) (*FixedQueryPlan, error) {\n\tif upd.OrderBy != nil || upd.Limit != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"%w: UPDATE must not have explicit ordering (have: %v) or limit clauses (have: %v): %v\",\n\t\t\tErrUnsupportedQueryConstruct,\n\t\t\tupd.OrderBy,\n\t\t\tupd.Limit,\n\t\t\tsqlparser.String(upd),\n\t\t)\n\t}\n\n\t// For updates on the _vt.vreplication table, we ban updates to the `id`\n\t// column, and allow updates to all other columns.\n\tfor _, expr := range upd.Exprs {\n\t\tif expr.Name.Name.EqualString(\"id\") {\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"%w %+v: %v\",\n\t\t\t\tErrCannotUpdateImmutableColumn,\n\t\t\t\texpr.Name.Name,\n\t\t\t\tsqlparser.String(expr),\n\t\t\t)\n\t\t}\n\t}\n\n\tupd.Where = addDefaultWheres(planner, upd.Where)\n\n\tbuf := sqlparser.NewTrackedBuffer(nil)\n\tbuf.Myprintf(\"%v\", upd)\n\n\treturn &FixedQueryPlan{\n\t\tParsedQuery: buf.ParsedQuery(),\n\t\tworkflow:    planner.workflow,\n\t\ttmc:         planner.tmc,\n\t}, nil","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/vexec/query_planner.go#L206-L242","documentation":"For UPDATEs on _vt.vreplication, the planner forbids modifying the immutable `id` column while allowing all other columns. An assignment to `id` is rejected with ErrCannotUpdateImmutableColumn, echoing the column name and the full assignment expression.","triggerScenarios":"Calling PlanQuery with an UPDATE on _vt.vreplication whose SET list contains an assignment to the `id` column (upd.Exprs entry with Name.Name == \"id\").","commonSituations":"Hand-written maintenance SQL that accidentally includes id in the SET list; ORM or code generator emitting full-row updates including the primary key; bulk UPDATE statements assigning all columns from a source row.","solutions":["Remove `id = ...` from the SET clause and update only mutable columns","If copying rows, enumerate explicit non-id columns instead of SELECT *-style full assignments","Identify the exact expression from the error message (`sqlparser.String(expr)`) and edit that statement"],"exampleFix":"// before\nUPDATE _vt.vreplication SET id = 42, state = 'Running' WHERE id = 7\n// after\nUPDATE _vt.vreplication SET state = 'Running' WHERE id = 7","handlingStrategy":"validation","validationCode":"if upd, ok := stmt.(*sqlparser.Update); ok {\n    for _, expr := range upd.Exprs {\n        if expr.Name.Name.EqualString(\"id\") {\n            return fmt.Errorf(\"cannot update immutable column id on _vt.vreplication\")\n        }\n    }\n}","typeGuard":"func updatableColumns(upd *sqlparser.Update) []string {\n    var cols []string\n    for _, expr := range upd.Exprs {\n        if !expr.Name.Name.EqualString(\"id\") {\n            cols = append(cols, expr.Name.Name.String())\n        }\n    }\n    return cols\n}","tryCatchPattern":"plan, err := planner.PlanQuery(ctx, stmt)\nif errors.Is(err, vexec.ErrCannotUpdateImmutableColumn) {\n    return fmt.Errorf(\"strip id from SET clause and retry: %w\", err)\n}","preventionTips":["Never include the `id` column in SET for _vt.vreplication updates","Enumerate explicit columns instead of building updates from full row copies","Add a lint/validator that rejects `id` assignments in vreplication UPDATEs before planning"],"tags":["go","vreplication","sql","update","immutable-column","vreplication-table"],"backgroundTag":"immutable-column-update","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}