vitessio/vitess · error
failed to parse options column: %v
Error message
failed to parse options column: %v
What it means
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>`.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/controller.go:107
tpCells []string
tpTabletTypesStr string
tpOptions discovery.TabletPickerOptions
}
// workflowTypeName returns the human-readable name for the workflow type
// (e.g. "OnlineDDL", "Reshard", "MoveTables").
func (ct *controller) workflowTypeName() string {
return binlogdatapb.VReplicationWorkflowType(ct.workflowType).String()
}
func processWorkflowOptions(params map[string]string) (*vttablet.VReplicationConfig, error) {
options, ok := params["options"]
if !ok {
options = "{}"
}
var workflowOptions vtctldata.WorkflowOptions
if err := json.Unmarshal([]byte(options), &workflowOptions); err != nil {
return nil, fmt.Errorf("failed to parse options column: %v", err)
}
workflowConfig, err := vttablet.NewVReplicationConfig(workflowOptions.Config)
if err != nil {
return nil, fmt.Errorf("failed to process config options: %v", err)
}
return workflowConfig, nil
}
// newController creates a new controller. Unless a stream is explicitly 'Stopped',
// this function launches a goroutine to perform continuous vreplication.
func 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) {
if blpStats == nil {
blpStats = binlogplayer.NewStats()
}
workflowConfig, err := processWorkflowOptions(params)
if err != nil {
return nil, err
}View on GitHub (pinned to 01a25a7d17)
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
Example fix
-- before
UPDATE _vt.vreplication SET options="{'config':'...'}" WHERE id=1; -- invalid JSON
-- after
UPDATE _vt.vreplication SET options='{"config":"..."}' WHERE id=1; Defensive patterns
Strategy: validation
Validate before calling
// validate the options column is JSON before creating/reusing the workflow
var v map[string]any
if err := json.Unmarshal([]byte(optionsCol), &v); err != nil {
return fmt.Errorf("options column is not valid JSON: %w", err)
} Type guard
func isValidJSONObject(s string) bool {
var m map[string]any
return s == "" || (json.Unmarshal([]byte(s), &m) == nil && m != nil)
} Try / catch
ct, err := newController(ctx, env, ...)
if err != nil {
if strings.Contains(err.Error(), "failed to parse options column") {
// repair: set options='{}' for the workflow row, then re-enable the stream
}
return err
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- stream needs a position or a table to copy
- partial row image encountered: ensure binlog_row_image is se
- failed to instantiate throttler: %v
- no binlog player client factory named %v
- failed to parse options column: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/3fadc81aa650cd03.
Report an issue: GitHub.