vitessio/vitess · error
failed to parse options column: %v
Error message
failed to parse options column: %v
What it means
The options column stores a JSON blob of WorkflowOptions for the stream. json.Unmarshal of its contents failed, meaning the column does not hold valid JSON. The default is "{}" when the SQL value is empty, so this error implies actual corrupt/non-JSON content.
Source
Thrown at go/vt/binlog/binlogplayer/binlog_player.go:616
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse stop_pos column: %v", err)
}
workflowType, err := vrRow.ToInt32("workflow_type")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse workflow_type column: %v", err)
}
workflowSubType, err := vrRow.ToInt32("workflow_sub_type")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse workflow_sub_type column: %v", err)
}
deferSecondaryKeys, err := vrRow.ToBool("defer_secondary_keys")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse defer_secondary_keys column: %v", err)
}
options := vrRow.AsString("options", "{}")
var workflowOptions vtctldata.WorkflowOptions
if err := json.Unmarshal([]byte(options), &workflowOptions); err != nil {
return VRSettings{}, fmt.Errorf("failed to parse options column: %v", err)
}
return VRSettings{
StartPos: startPos,
StopPos: stopPos,
MaxTPS: maxTPS,
MaxReplicationLag: maxReplicationLag,
State: binlogdatapb.VReplicationWorkflowState(binlogdatapb.VReplicationWorkflowState_value[vrRow.AsString("state", "")]),
WorkflowType: binlogdatapb.VReplicationWorkflowType(workflowType),
WorkflowName: vrRow.AsString("workflow", ""),
WorkflowSubType: binlogdatapb.VReplicationWorkflowSubType(workflowSubType),
DeferSecondaryKeys: deferSecondaryKeys,
WorkflowOptions: &workflowOptions,
}, nil
}
// CreateVReplication returns a statement to populate the first value into
// the _vt.vreplication table.
func CreateVReplication(workflow string, source *binlogdatapb.BinlogSource, position string, maxTPS, maxReplicationLag, timeUpdated int64, dbName string,View on GitHub (pinned to 01a25a7d17)
Solutions
- Inspect: `select uid, options from _vt.vreplication where uid=<id>` and validate the text is well-formed JSON.
- Reset to a valid empty object: `update _vt.vreplication set options='{}' where uid=<id>` if options are not essential, or re-enter the correct JSON (properly quoted via VExec to avoid shell escaping issues).
- If options carry required workflow state (e.g. source/ target keyspaces), re-create the workflow rather than hand-crafting the JSON.
- Find and stop any external tool writing to the column.
Example fix
// before: invalid JSON (unquoted keys)
update _vt.vreplication set options='{source: "ks"}' where uid=1;
// after: valid JSON, or reset to empty
update _vt.vreplication set options='{}' where uid=1; Defensive patterns
Strategy: validation
Validate before calling
qr, _ := dbClient.ExecuteFetch(fmt.Sprintf("SELECT options FROM _vt.vreplication WHERE uid=%d", uid), 1)
if len(qr.Rows) == 1 {
opts := qr.Named().Row().AsString("options", "")
var wo vtctldatapb.WorkflowOptions
if err := json.Unmarshal([]byte(opts), &wo); err != nil {
return fmt.Errorf("options %q is not valid JSON; reset to '{}' or re-create the workflow", opts)
}
} Type guard
func isValidWorkflowOptionsJSON(s string) bool {
var wo vtctldatapb.WorkflowOptions
return json.Unmarshal([]byte(s), &wo) == nil
} Try / catch
settings, err := binlogplayer.ReadVRSettings(dbClient, uid)
if err != nil && strings.Contains(err.Error(), "failed to parse options") {
// reset to empty options and retry once
_, _ = dbClient.ExecuteFetch(fmt.Sprintf("UPDATE _vt.vreplication SET options='{}' WHERE uid=%d", uid), 0)
settings, err = binlogplayer.ReadVRSettings(dbClient, uid)
} Prevention
- Write the options column only via the workflow API.
- When editing JSON manually, validate it (e.g. jq) before committing.
- Prefer resetting to '{}' over hand-crafting complex options.
- Quote JSON through VExec parameters to avoid shell escaping bugs.
When it happens
Trigger: json.Unmarshal([]byte(options)) fails: options contains truncated JSON, plain text, single-quoted pseudo-JSON from manual edits, or binary garbage written by an external tool.
Common situations: Manual edits to _vt.vreplication writing unquoted/invalid JSON; interrupted writes; migration scripts rewriting the column without escaping.
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
- failed to parse max_tps column: %v
- failed to parse max_replication_lag column: %v
- failed to parse pos column: %v
- failed to parse stop_pos column: %v
- range %d should be >= %d
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/18387d7ce4c20503.
Report an issue: GitHub.