{"record":{"id":"3fadc81aa650cd03","repo":"vitessio/vitess","slug":"failed-to-parse-options-column-v-3fadc8","errorCode":null,"errorMessage":"failed to parse options column: %v","messagePattern":"failed to parse options column: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/controller.go","lineNumber":107,"sourceCode":"\ttpCells          []string\n\ttpTabletTypesStr string\n\ttpOptions        discovery.TabletPickerOptions\n}\n\n// workflowTypeName returns the human-readable name for the workflow type\n// (e.g. \"OnlineDDL\", \"Reshard\", \"MoveTables\").\nfunc (ct *controller) workflowTypeName() string {\n\treturn binlogdatapb.VReplicationWorkflowType(ct.workflowType).String()\n}\n\nfunc processWorkflowOptions(params map[string]string) (*vttablet.VReplicationConfig, error) {\n\toptions, ok := params[\"options\"]\n\tif !ok {\n\t\toptions = \"{}\"\n\t}\n\tvar workflowOptions vtctldata.WorkflowOptions\n\tif err := json.Unmarshal([]byte(options), &workflowOptions); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse options column: %v\", err)\n\t}\n\tworkflowConfig, err := vttablet.NewVReplicationConfig(workflowOptions.Config)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to process config options: %v\", err)\n\t}\n\treturn workflowConfig, nil\n}\n\n// newController creates a new controller. Unless a stream is explicitly 'Stopped',\n// this function launches a goroutine to perform continuous vreplication.\nfunc newController(ctx context.Context, params map[string]string, dbClientFactory func() binlogplayer.DBClient, mysqld mysqlctl.MysqlDaemon, ts *topo.Server, cell string, blpStats *binlogplayer.Stats, vre *Engine, tpo discovery.TabletPickerOptions) (*controller, error) {\n\tif blpStats == nil {\n\t\tblpStats = binlogplayer.NewStats()\n\t}\n\tworkflowConfig, err := processWorkflowOptions(params)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/controller.go#L89-L125","documentation":"When creating a vreplication controller, the workflow's `options` column (default `{}`) is unmarshaled into vtctldata.WorkflowOptions. If the stored text is not valid JSON or has the wrong shape, processWorkflowOptions returns `failed to parse options column: <err>`.","triggerScenarios":"The _vt.vreplication `options` column contains malformed JSON (truncated value, single quotes instead of double, non-JSON text), or a JSON value incompatible with the WorkflowOptions proto (e.g. a JSON array/string instead of an object).","commonSituations":"Manual edits to _vt.vreplication rows; workflows written by older Vitess versions storing a legacy options format; corruption from a partial update; external tools writing to the options column.","solutions":["Inspect the `options` column for the workflow row in _vt.vreplication on the target primary and fix it to be valid JSON (usually `{}` if unused)","Reset the options to the default `{}` for legacy workflows that never used options","Restore the row from a backup if the value was corrupted, or recreate the workflow","Verify the writing tool/version is compatible with the current Vitess WorkflowOptions format"],"exampleFix":"-- before\nUPDATE _vt.vreplication SET options=\"{'config':'...'}\" WHERE id=1; -- invalid JSON\n-- after\nUPDATE _vt.vreplication SET options='{\"config\":\"...\"}' WHERE id=1;","handlingStrategy":"validation","validationCode":"// validate the options column is JSON before creating/reusing the workflow\nvar v map[string]any\nif err := json.Unmarshal([]byte(optionsCol), &v); err != nil {\n  return fmt.Errorf(\"options column is not valid JSON: %w\", err)\n}","typeGuard":"func isValidJSONObject(s string) bool {\n  var m map[string]any\n  return s == \"\" || (json.Unmarshal([]byte(s), &m) == nil && m != nil)\n}","tryCatchPattern":"ct, err := newController(ctx, env, ...) \nif err != nil {\n  if strings.Contains(err.Error(), \"failed to parse options column\") {\n    // repair: set options='{}' for the workflow row, then re-enable the stream\n  }\n  return err\n}","preventionTips":["Never write non-JSON text into _vt.vreplication.options","Use double quotes / valid JSON when editing options","Reset legacy rows to '{}' if they predate options support","Let vtctldclient manage workflow state instead of raw SQL edits"],"tags":["vreplication","json","configuration"],"backgroundTag":"invalid-json-options-column","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}