go-delve/delve · warning
%v
Error message
%v
What it means
constantUnaryOp wraps go/constant's constant.UnaryOp and converts any panic it triggers into an error via fmt.Errorf("%v", recover()). The message text is therefore whatever the go/constant runtime panicked with (e.g. an invalid unary operation on the constant's kind). It is a defensive wrapper so a malformed constant never crashes the debugger.
Source
Thrown at pkg/proc/eval.go:2363
}
stack.push(xev.pointerToVariable())
}
func (v *Variable) pointerToVariable() *Variable {
v.OnlyAddr = true
rv := v.newVariable("", 0, godwarf.FakePointerType(v.DwarfType, int64(v.bi.Arch.PtrSize())), v.mem)
rv.Children = []Variable{*v}
rv.loaded = true
return rv
}
func constantUnaryOp(op token.Token, y constant.Value) (r constant.Value, err error) {
defer func() {
if ierr := recover(); ierr != nil {
err = fmt.Errorf("%v", ierr)
}
}()
r = constant.UnaryOp(op, y, 0)
return
}
func constantBinaryOp(op token.Token, x, y constant.Value) (r constant.Value, err error) {
defer func() {
if ierr := recover(); ierr != nil {
err = fmt.Errorf("%v", ierr)
}
}()
switch op {
case token.SHL, token.SHR:
n, _ := constant.Uint64Val(y)
r = constant.Shift(x, op, uint(n))
default:
r = constant.BinaryOp(x, op, y)View on GitHub (pinned to a23773e6c3)
Solutions
- Check the operand type with `print x` and use an operator valid for it (negate ints/floats, `!` for bools, `^` for ints).
- If the operand is a string, convert first (e.g. use `len(x)` or parse to a number) instead of applying arithmetic.
- If the value itself looks corrupt, re-read it fresh (`print x`) or restart the session; the constant may come from a bad memory read.
- Report persistent panics with the exact expression to go-delve/delve — the panic text comes from go/constant and may indicate an unhandled value kind.
Example fix
// before
(dlv) print -"hello"
// panic converted to: <go/constant panic text>
// after
(dlv) print len("hello") // string ops via valid builtins
(dlv) print -n // unary minus only on numeric values Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the operand supports the unary op: (dlv) print x // string? bool? use the right operator // numeric -> -x or ^x; bool -> !x
Type guard
func supportsUnaryMinus(v interface{}) bool {
switch reflect.TypeOf(v).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Float32, reflect.Float64:
return true
}
return false
} Try / catch
// Delve already converts the panic to an error; on the client side (rpc2):
res, err := client.EvalVariable(scope, expr, cfg)
if err != nil && strings.Contains(err.Error(), "invalid operation") {
// re-issue with a corrected expression
} Prevention
- Match the unary operator to the operand kind (numeric vs bool).
- Never apply - or ^ to strings or bools.
- Print the operand first if its kind is unclear.
When it happens
Trigger: Evaluating a unary expression (-x, +x, ^x, !x) at the debugger prompt where xv.Value is a constant.Value that go/constant cannot handle for that operator — e.g. `-"string"`, `^1.5`, or a constant produced from a corrupt/odd value read from debuggee memory.
Common situations: Applying numeric negation to a string constant, bitwise complement of a float, or exotic unary ops on values reconstructed from unusual memory states. Rare in normal use because earlier checks catch nil values and special floats.
Related errors
- operator %s can not be applied to %q
- 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
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/bb9b91e726986ea4.
Report an issue: GitHub.