vitessio/vitess · error
unexpected token '%s' at %s
Error message
unexpected token '%s' at %s
What it means
ParseRows is a small state machine over a scanner. When the next token does not advance the parser to a valid state (e.g. a non-')' token where a value list must close), the state becomes stInvalid and this error is reported with the offending token and its position, just before returning io.ErrUnexpectedEOF if input is exhausted.
Source
Thrown at go/sqltypes/parse_rows.go:115
switch tok {
case scanner.String:
var err error
literal, err = strconv.Unquote(literal)
if err != nil {
return nil, fmt.Errorf("failed to parse literal string at %s: %w", scan.Position, err)
}
fallthrough
case scanner.Int, scanner.Float:
row = append(row, MakeTrusted(Type(vtype), []byte(literal)))
next = stInValue2
}
case stInValue2:
if tok == ')' {
next = stInRow
}
}
if next == stInvalid {
return nil, fmt.Errorf("unexpected token '%s' at %s", scan.TokenText(), scan.Position)
}
st = next
}
return nil, io.ErrUnexpectedEOF
}
type RowMismatchError struct {
err error
want, got []Row
}
func (e *RowMismatchError) Error() string {
return fmt.Sprintf("results differ: %v\n\twant: %v\n\tgot: %v", e.err, e.want, e.got)
}
func RowEqual(want, got Row) bool {
return slices.EqualFunc(want, got, func(a, b Value) bool {
return a.Equal(b)View on GitHub (pinned to 01a25a7d17)
Solutions
- Correct the row syntax in the expected string: each row must be (v1, v2, ...) separated by commas
- Check the reported position (scan.Position) to find the stray token
- Compare against the exact output format the test helper expects
Example fix
// before want := "(1 2)(3 4)" // after want := "(1, 2), (3, 4)"
Defensive patterns
Strategy: validation
Validate before calling
if !strings.HasPrefix(wantStr, "(") || !strings.HasSuffix(wantStr, ")") {
return fmt.Errorf("rows must look like (v, v), (v, v)")
} Try / catch
_, err := sqltypes.ParseRows(wantStr)
if err != nil {
t.Fatalf("fixture syntax error: %v", err)
} Prevention
- Format expected rows strictly as (v1, v2), (v1, v2)
- Never include column headers or semicolons in the expected string
- Validate fixtures once in TestMain
When it happens
Trigger: Calling ParseRows/RowsEqualsStr with malformed row syntax: missing comma between rows, missing closing parenthesis, stray characters, or an empty value list such as "(1, 2 3)".
Common situations: Hand-written expected-result strings in tests (AssertMatchesNoOrder etc.) with typos; copy-pasted SQL output that includes headers or extra whitespace/comments the mini-parser rejects.
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 literal string at %s: %w
- malformed row assertion: %w
- stray %% at the end of pattern
- overflow
- too many .s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/89828ad81643e748.
Report an issue: GitHub.