{"record":{"id":"6f17dd11e9056c96","repo":"vitessio/vitess","slug":"panic-err-6f17dd","errorCode":null,"errorMessage":"panic(err)","messagePattern":"panic\\(err\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/evalengine/eval_result.go","lineNumber":86,"sourceCode":"// TupleValues allows for retrieval of the value we expose for public consumption\nfunc (er EvalResult) TupleValues() []sqltypes.Value {\n\t// TODO: Make this collation-aware\n\tswitch v := er.v.(type) {\n\tcase *evalTuple:\n\t\tresult := make([]sqltypes.Value, 0, len(v.t))\n\t\tfor _, val := range v.t {\n\t\t\tresult = append(result, evalToSQLValue(val))\n\t\t}\n\t\treturn result\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc (er EvalResult) MustBoolean() bool {\n\tb, err := er.ToBooleanStrict()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn b\n}\n\nfunc (er EvalResult) ToBoolean() bool {\n\treturn evalIsTruthy(er.v) == boolTrue\n}\n\n// ToBooleanStrict is used when the casting to a boolean has to be minimally forgiving,\n// such as when assigning to a system variable that is expected to be a boolean\nfunc (er EvalResult) ToBooleanStrict() (bool, error) {\n\tswitch v := er.v.(type) {\n\tcase *evalInt64:\n\t\tswitch v.i {\n\t\tcase 0:\n\t\t\treturn false, nil\n\t\tcase 1:\n\t\t\treturn true, nil","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/evalengine/eval_result.go#L68-L104","documentation":"EvalResult.MustBoolean asserts that the result can be strictly converted to a boolean; if ToBooleanStrict returns an error the Must* contract panics with that error. Must* methods are for call sites that already know the value is boolean-coercible.","triggerScenarios":"Calling MustBoolean on an EvalResult whose underlying value is not strictly boolean — e.g. a string, integer, or NULL result from expression evaluation passed to MustBoolean.","commonSituations":"Developers using MustBoolean on arbitrary query results instead of checking ToBooleanStrict first; value returned from a comparison changed shape after a refactor.","solutions":["Replace MustBoolean with ToBooleanStrict and handle the error","Only call MustBoolean on results known to come from boolean-producing expressions","Add a type/type check on the underlying value before calling"],"exampleFix":"// before\nb := result.MustBoolean()\n// after\nb, err := result.ToBooleanStrict()\nif err != nil {\n    return vterrors.Wrapf(err, \"expected boolean result\")\n}","handlingStrategy":"try-catch","validationCode":"// check strict convertibility first\nif _, err := er.ToBooleanStrict(); err != nil {\n    return vterrors.Wrapf(err, \"result is not a boolean\")\n}","typeGuard":"func isStrictBoolean(er EvalResult) bool {\n    _, err := er.ToBooleanStrict()\n    return err == nil\n}","tryCatchPattern":"func safeMustBoolean(er EvalResult) (b bool, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, \"MustBoolean: %v\", r)\n        }\n    }()\n    return er.MustBoolean(), nil\n}","preventionTips":["Prefer ToBooleanStrict in library/infrastructure code; reserve Must* for invariant-proven call sites","Only call MustBoolean on results of boolean expressions (comparisons, logical ops)","Document on wrappers that the input must be boolean-producing"],"tags":["go","panic","evalengine","must-assert"],"backgroundTag":"must-assertion-panic","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}