{"record":{"id":"5b0545a5a9e3705a","repo":"vitessio/vitess","slug":"input-is-not-a-slice","errorCode":null,"errorMessage":"input is not a slice","messagePattern":"input is not a slice","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/sqlparser/tracked_buffer.go","lineNumber":271,"sourceCode":"\t\tbuf.formatter(expr)\n\t\tprefix = \", \"\n\t}\n}\n\nfunc (buf *TrackedBuffer) formatNodes(input any) {\n\tswitch nodes := input.(type) {\n\tcase []Expr:\n\t\tbuf.formatExprs(nodes)\n\t\treturn\n\t}\n\n\t// SLOW PATH! Add specific cases above to avoid reflection.\n\n\t// Check if the input is a slice\n\tval := reflect.ValueOf(input)\n\tif val.Kind() != reflect.Slice {\n\t\t// Handle the error or return if input is not a slice\n\t\tpanic(\"input is not a slice\")\n\t}\n\n\t// Iterate over the slice elements\n\tfor i := 0; i < val.Len(); i++ {\n\t\telem := val.Index(i).Interface()\n\n\t\t// Assert each element implements SQLNode\n\t\tnode, ok := elem.(SQLNode)\n\t\tif !ok {\n\t\t\t// Handle the error or skip non-SQLNode elements\n\t\t\tpanic(\"element does not implement SQLNode\")\n\t\t}\n\n\t\t// Now `node` is of type SQLNode\n\t\t// You can call methods or use it as a SQLNode here\n\t\tbuf.Myprintf(\"%v\", node)\n\t}\n}","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/sqlparser/tracked_buffer.go#L253-L289","documentation":"Error in sqlparser's tracked_buffer (used for AST formatting/generation): a value expected to be a slice (list of child nodes) is not a slice, so it cannot be walked. Thrown at go/vt/sqlparser/tracked_buffer.go:271.","triggerScenarios":"An AST Format method passes a single SQLNode (not a slice) with the %n verb, e.g. buf.Myprintf(\"%n\", singleNode) instead of %v.","commonSituations":"Confusing %n (slice-of-nodes) with %v (single node) when writing or editing Format methods for nodes containing lists (e.g. TableExprs, SelectExprs).","solutions":["Wrap the node in a slice: buf.Myprintf(\"%n\", []SQLNode{node})","Or use %v for a single SQLNode value","Verify with a ToString() test for the affected node"],"exampleFix":"// before\nbuf.Myprintf(\"%n\", node.Exprs[0])\n// after\nbuf.Myprintf(\"%n\", node.Exprs)","handlingStrategy":"validation","validationCode":"rv := reflect.ValueOf(v)\nif rv.Kind() != reflect.Slice {\n    return fmt.Errorf(\"%%n requires a slice, got %T\", v)\n}","typeGuard":"func isSQLNodeSlice(v any) bool {\n    rv := reflect.ValueOf(v)\n    if rv.Kind() != reflect.Slice {\n        return false\n    }\n    for i := 0; i < rv.Len(); i++ {\n        if _, ok := rv.Index(i).Interface().(SQLNode); !ok {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Use %v for single nodes and %n only for slices of SQLNodes","Wrap a lone node in a slice literal when using %n","Document verb semantics in new Format methods"],"tags":["sqlparser","tracked-buffer","reflection","panic","ast"],"backgroundTag":"format-string-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}