{"record":{"id":"8a83e8c2a558d551","repo":"vitessio/vitess","slug":"flagutil-optionalflagvalue-has-no-parse-function","errorCode":null,"errorMessage":"flagutil: OptionalFlagValue has no parse function; use a constructor such as NewOptionalFlag","messagePattern":"flagutil: OptionalFlagValue has no parse function; use a constructor such as NewOptionalFlag","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"go/flagutil/optional.go","lineNumber":124,"sourceCode":"\n// NewOptionalFlag returns a *OptionalFlagValue[T] with the given default value,\n// pflag type name, parse function, and stringer.\n// It returns an error if parse is nil, since a flag without a parse function cannot be set.\nfunc NewOptionalFlag[T any](defaultVal T, typeName string, parse func(string) (T, error), stringer func(T) string) (*OptionalFlagValue[T], error) {\n\tif parse == nil {\n\t\treturn nil, errors.New(\"flagutil: NewOptionalFlag requires a non-nil parse function\")\n\t}\n\treturn &OptionalFlagValue[T]{\n\t\tval:      defaultVal,\n\t\ttypeName: typeName,\n\t\tparse:    parse,\n\t\tstringer: stringer,\n\t}, nil\n}\n\nfunc (f *OptionalFlagValue[T]) Set(arg string) error {\n\tif f.parse == nil {\n\t\treturn errors.New(\"flagutil: OptionalFlagValue has no parse function; use a constructor such as NewOptionalFlag\")\n\t}\n\n\tv, err := f.parse(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tf.val = v\n\tf.set = true\n\n\treturn nil\n}\n\nfunc (f *OptionalFlagValue[T]) String() string {\n\tif f.stringer == nil {\n\t\treturn fmt.Sprintf(\"%v\", f.val)\n\t}\n","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/flagutil/optional.go#L106-L142","documentation":"Returned when the zero-value OptionalFlagValue is used as a flag without one of the NewOptional* constructors, so it has no parse function registered. Construct the value with flagutil.NewOptionalBool/NewOptionalInt64/etc. instead of declaring a bare OptionalFlagValue.","triggerScenarios":"Calling Cluster.GetVSchema while topoReadPool is exhausted and the request context expires during Acquire.","commonSituations":"Heavy concurrent vtadmin traffic; slow topo backend; short client deadlines.","solutions":["Retry the request","Increase topoReadPool size or throttle callers","Diagnose topo server latency causing long slot occupancy"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"v, err := cluster.GetVSchema(ctx, ks)\nif err != nil && errors.Is(err, context.DeadlineExceeded) {\n\tv, err = cluster.GetVSchema(ctxWithRetry, ks)\n}","preventionTips":["Serialize vschema reads or batch them via GetVSchemas","Increase topoReadPool size","Monitor topo read latency"],"tags":["vtadmin","topology","concurrency","vschema"],"backgroundTag":"semaphore-acquire-timeout","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}