{"record":{"id":"ba0722401d709c43","repo":"vitessio/vitess","slug":"bad-literal-argument","errorCode":null,"errorMessage":"bad literal argument","messagePattern":"bad literal argument","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/tools/astfmtgen/main.go","lineNumber":169,"sourceCode":"}\n\nfunc (r *Rewriter) rewriteLiteral(rcv ast.Expr, method string, arg ast.Expr) ast.Stmt {\n\texpr := &ast.CallExpr{\n\t\tFun: &ast.SelectorExpr{\n\t\t\tX:   rcv,\n\t\t\tSel: &ast.Ident{Name: method},\n\t\t},\n\t\tArgs: []ast.Expr{arg},\n\t}\n\treturn &ast.ExprStmt{X: expr}\n}\n\nfunc (r *Rewriter) rewriteAstPrintf(cursor *astutil.Cursor, expr *ast.CallExpr) bool {\n\tcallexpr := expr.Fun.(*ast.SelectorExpr)\n\tlit := expr.Args[1].(*ast.BasicLit)\n\tformat, err := strconv.Unquote(lit.Value)\n\tif err != nil {\n\t\tpanic(\"bad literal argument\")\n\t}\n\n\tend := len(format)\n\tfieldnum := 0\n\tfor i := 0; i < end; {\n\t\tlasti := i\n\t\tfor i < end && format[i] != '%' {\n\t\t\ti++\n\t\t}\n\t\tif i > lasti {\n\t\t\tvar arg ast.Expr\n\t\t\tvar method string\n\t\t\tlit := format[lasti:i]\n\n\t\t\tif len(lit) == 1 {\n\t\t\t\tmethod = \"WriteByte\"\n\t\t\t\targ = &ast.BasicLit{\n\t\t\t\t\tKind:  gotoken.CHAR,","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/tools/astfmtgen/main.go#L151-L187","documentation":"astfmtgen's rewriteAstPrintf rewrites fmt-style calls in generated code; it assumes the format argument is a quoted string literal (ast.BasicLit) so it can parse the format directives. If strconv.Unquote fails, the second argument was not a valid string literal and the tool panics. This is a developer-time code-generation tool, so panicking is intentional fail-fast behavior.","triggerScenarios":"Running go generate / astfmtgen against a printf-style call whose second argument is a non-literal string (a variable, concatenation, backtick oddity, or wrong argument position).","commonSituations":"Changing ast_printf/ast_sprintf calls to use a computed format string; reordering arguments so the literal is no longer Args[1]; introducing malformed quoting in the format string.","solutions":["Make the format argument a plain string literal, e.g. ast_sprintf(node, \"foo %n bar\", xs).","Check argument order so the format literal is the second argument.","If the format must be dynamic, hoist the formatting out of the rewritten call or extend the tool to handle it."],"exampleFix":"// before\nast_sprintf(expr, formatString, args) // panics: bad literal argument\n// after\nast_sprintf(expr, \"expected format %n\", args)","handlingStrategy":"validation","validationCode":"// ensure the format arg of an ast_printf/ast_sprintf call is a quoted string literal\nsel, ok := call.Args[1].(*ast.BasicLit)\nif !ok || sel.Kind != token.STRING {\n    return fmt.Errorf(\"format must be a string literal, got %T\", call.Args[1])\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass literal format strings to ast_printf/ast_sprintf calls.","Run `go generate` locally before committing generated-code changes.","Keep the format literal in the fixed second-argument position."],"tags":["go","codegen","tooling","panic","astfmtgen"],"backgroundTag":"invalid-literal-format","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}