go-delve/delve · error

shift count must not be negative

Error message

shift count must not be negative

What it means

Delve's expression evaluator supports the shift operators << and >> on Go values. Before applying a shift it validates the shift count: it must be an integer of any signedness, but its value must not be negative, and non-integer types are rejected entirely. This error is thrown when the right-hand operand of a shift is a signed integer with a negative constant value.

Source

Thrown at pkg/proc/eval.go:2446

	if xv == nilVariable {
		return nil, negotiateTypeNil(op, yv)
	}

	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 {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Inspect the shift count expression before the shift, e.g. 'print n' or 'print i-j', and fix the underlying negative value
  2. Guard the shift in the source: if n >= 0 { x << n } else { ... }
  3. Reinterpret the count as unsigned if negative values are impossible in your logic: uint(n)
  4. If the variable display seems wrong, verify the variable's type/value with 'locals' or 'print' to confirm it is truly negative

Example fix

// before (evaluating in dlv)
(dlv) print x << n        // n = -3 -> error

// after
(dlv) print n             // inspect first
-3
(dlv) print uint(x) >> 3  // or fix n in the program before shifting
Defensive patterns

Strategy: validation

Validate before calling

// before evaluating a shift in the debugger
if n, ok := shiftCount.(int64); !ok || n < 0 {
    // fix the count or use uint(n) in the expression
    fmt.Println("shift count must be a non-negative integer, got", n)
}

Type guard

func validShiftCount(v interface{}) bool {
    switch c := v.(type) {
    case uint, uint8, uint16, uint32, uint64:
        return true
    case int:
        return c >= 0
    case int64:
        return c >= 0
    default:
        return false
    }
}

Prevention

When it happens

Trigger: Evaluating an expression like 'a << b' or 'a >> b' in the dlv debugger (eval, print, or watch commands) where b is a signed integer variable holding a negative value, e.g. 'print x << n' with n == -1.

Common situations: Stepping through bit-manipulation code where the shift amount is computed (e.g. from a subtraction or loop counter) and has gone negative due to an off-by-one or uninitialized value; debugging the very bug the Go compiler would reject as a constant expression.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/e09f4633451c7bcf. Report an issue: GitHub.