{"record":{"id":"a1692e36104082d4","repo":"go-delve/delve","slug":"operator-s-not-defined-on-s","errorCode":null,"errorMessage":"operator %s not defined on %s","messagePattern":"operator (.+?) not defined on (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/eval.go","lineNumber":2635,"sourceCode":"\t\t\t\treturn false, nil\n\t\t\tcase token.NEQ:\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t\tif xv.Kind == reflect.String {\n\t\t\txv.loadValue(loadFullValueLongerStrings)\n\t\t}\n\t\tif yv.Kind == reflect.String {\n\t\t\tyv.loadValue(loadFullValueLongerStrings)\n\t\t}\n\t\tif int64(len(constant.StringVal(xv.Value))) != xv.Len || int64(len(constant.StringVal(yv.Value))) != yv.Len {\n\t\t\treturn false, errors.New(\"string too long for comparison\")\n\t\t}\n\t\treturn constantCompare(op, xv.Value, yv.Value)\n\t}\n\n\tif op != token.EQL && op != token.NEQ {\n\t\treturn false, fmt.Errorf(\"operator %s not defined on %s\", op.String(), xv.Kind.String())\n\t}\n\n\tvar eql bool\n\tvar err error\n\n\tif xv == nilVariable {\n\t\tswitch op {\n\t\tcase token.EQL:\n\t\t\treturn yv.isNil(), nil\n\t\tcase token.NEQ:\n\t\t\treturn !yv.isNil(), nil\n\t\t}\n\t}\n\n\tif yv == nilVariable {\n\t\tswitch op {\n\t\tcase token.EQL:\n\t\t\treturn xv.isNil(), nil","sourceCodeStart":2617,"sourceCodeEnd":2653,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/eval.go#L2617-L2653","documentation":"Once constant folding is ruled out, compareOp handles comparisons on loaded variables. Only == and != are defined for most kinds; ordering operators (<, <=, >, >=) are only valid on numbers and strings. When an ordering operator reaches this point with a kind like bool, pointer, or struct, Delve reports that the operator is not defined on that kind.","triggerScenarios":"Evaluating `p ptr1 < ptr2`, `p boolVar <= boolVar2`, or any relational op on non-ordered kinds; triggered when op is not EQL/NEQ and the operands weren't handled by the constant path.","commonSituations":"Trying to order pointers or booleans (illegal in Go too), or comparing structs with <; usually a misunderstanding that the debugger follows the same operator rules as the language.","solutions":["Use == or != for kinds without ordering, or compare a numeric member: `p a.field < b.field`.","Convert pointers via uintptr for debugging purposes: `p uintptr(p1) < uintptr(p2)`.","Check the kind with `print x` before using relational operators."],"exampleFix":"// before\np p1 < p2\n// after\np uintptr(p1) < uintptr(p2)","handlingStrategy":"validation","validationCode":"// only numbers and strings support ordering\nordered := map[reflect.Kind]bool{\n    reflect.Int: true, reflect.Int8: true, reflect.Int16: true, reflect.Int32: true, reflect.Int64: true,\n    reflect.Uint: true, reflect.Uint8: true, reflect.Uint16: true, reflect.Uint32: true, reflect.Uint64: true,\n    reflect.Float32: true, reflect.Float64: true, reflect.String: true,\n}\nif !ordered[v.Kind] {\n    // use == / != or compare a numeric field instead\n}","typeGuard":"func supportsOrdering(k reflect.Kind) bool {\n    switch k {\n    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n        reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,\n        reflect.Float32, reflect.Float64, reflect.String:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Use < only on numeric and string values.","For pointers, cast via uintptr() when probing order in the debugger.","Compare struct fields instead of whole aggregates."],"tags":["debugger","expression-evaluation","invalid-operator"],"backgroundTag":"operator-not-defined-on-type","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}