go-delve/delve · error
operator %s not defined on %s
Error message
operator %s not defined on %s
What it means
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.
Source
Thrown at pkg/proc/eval.go:2635
return false, nil
case token.NEQ:
return true, nil
}
}
if xv.Kind == reflect.String {
xv.loadValue(loadFullValueLongerStrings)
}
if yv.Kind == reflect.String {
yv.loadValue(loadFullValueLongerStrings)
}
if int64(len(constant.StringVal(xv.Value))) != xv.Len || int64(len(constant.StringVal(yv.Value))) != yv.Len {
return false, errors.New("string too long for comparison")
}
return constantCompare(op, xv.Value, yv.Value)
}
if op != token.EQL && op != token.NEQ {
return false, fmt.Errorf("operator %s not defined on %s", op.String(), xv.Kind.String())
}
var eql bool
var err error
if xv == nilVariable {
switch op {
case token.EQL:
return yv.isNil(), nil
case token.NEQ:
return !yv.isNil(), nil
}
}
if yv == nilVariable {
switch op {
case token.EQL:
return xv.isNil(), nilView on GitHub (pinned to a23773e6c3)
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.
Example fix
// before p p1 < p2 // after p uintptr(p1) < uintptr(p2)
Defensive patterns
Strategy: validation
Validate before calling
// only numbers and strings support ordering
ordered := map[reflect.Kind]bool{
reflect.Int: true, reflect.Int8: true, reflect.Int16: true, reflect.Int32: true, reflect.Int64: true,
reflect.Uint: true, reflect.Uint8: true, reflect.Uint16: true, reflect.Uint32: true, reflect.Uint64: true,
reflect.Float32: true, reflect.Float64: true, reflect.String: true,
}
if !ordered[v.Kind] {
// use == / != or compare a numeric field instead
} Type guard
func supportsOrdering(k reflect.Kind) bool {
switch k {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64, reflect.String:
return true
}
return false
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- shift count must not be negative
- invalid argument %s (type %s) for cap
- wrong number of arguments to len: %d
- invalid argument %s (type %s) for len
- wrong number of arguments to complex: %d
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/a1692e36104082d4.
Report an issue: GitHub.