go-delve/delve · error
shift count type %s, must be unsigned integer
Error message
shift count type %s, must be unsigned integer
What it means
Delve's expression evaluator requires the right-hand operand of a shift (<< or >>) to be an unsigned integer. When the shift-count variable's reflect.Kind is not one of the signed int kinds that passed the earlier checks (i.e. it's a float, string, struct, etc.), the evaluator rejects it with this message. It mirrors Go's compile-time rule that shift counts must be unsigned integers.
Source
Thrown at pkg/proc/eval.go:2449
if yv == nilVariable {
return nil, negotiateTypeNil(op, xv)
}
if op == token.SHR || op == token.SHL {
if xv.Value == nil || xv.Value.Kind() != constant.Int {
return nil, fmt.Errorf("shift of type %s", xv.Kind)
}
switch yv.Kind {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
// ok
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if constant.Sign(yv.Value) < 0 {
return nil, errors.New("shift count must not be negative")
}
default:
return nil, fmt.Errorf("shift count type %s, must be unsigned integer", yv.Kind.String())
}
return xv.DwarfType, nil
}
if xv.DwarfType == nil && yv.DwarfType == nil {
return nil, nil
}
if xv.DwarfType != nil && yv.DwarfType != nil {
if xv.DwarfType.String() != yv.DwarfType.String() {
return nil, fmt.Errorf("mismatched types %q and %q", xv.DwarfType.String(), yv.DwarfType.String())
}
return xv.DwarfType, nil
} else if xv.DwarfType != nil && yv.DwarfType == nil {
if err := yv.isType(xv.DwarfType, xv.Kind); err != nil {
return nil, err
}View on GitHub (pinned to a23773e6c3)
Solutions
- Cast the shift count to an unsigned integer: `x << uint(y)`.
- If the count is a float, convert to int first: `x << uint(int(f))`.
- Inspect the count variable (`print y`) to confirm its type is what you expect.
Example fix
// before p x << y // y is float64 // after p x << uint(y)
Defensive patterns
Strategy: validation
Validate before calling
// before: x << y
if v, err := eval("y"); err == nil {
switch v.Kind {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
// ok
default:
y = uint(y) // cast the shift count before shifting
}
} Type guard
func isUnsignedKind(k reflect.Kind) bool {
switch k {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return true
}
return false
} Prevention
- Always cast shift counts explicitly: uint(n).
- Never shift by float or signed values without conversion.
- Print the count variable in Delve before using it in a shift expression.
When it happens
Trigger: Evaluating an expression like `x << y` in the debugger where y is a negative int (handled separately), a float64, or a non-numeric kind such as string, bool, slice or struct. Reached via EvalScope.evaluateBinaryOp with op token.SHL/token.SHR and the shift-count variable's Kind outside the int/uint set.
Common situations: Debugging session where the user writes `buf >> 4.0` or `flags << someStringVar`; typical for someone testing bit-manipulation logic interactively and forgetting the operand types differ from what they assume in source.
Related errors
- invalid argument 1 %s (type %s) to complex
- invalid argument 2 %s (type %s) to complex
- invalid argument %s (type %s) to imag
- invalid argument %s (type %s) to real
- can not slice %q (type %s)
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/3cac7f65b8482741.
Report an issue: GitHub.