go-delve/delve · error

expression %q (%s) can not be dereferenced

Error message

expression %q (%s) can not be dereferenced

What it means

Thrown by evalPointerDeref when a dereference expression *x is evaluated but the operand's kind is not reflect.Ptr. Only pointer-typed values can be dereferenced; dereferencing an int, float, string, map, etc. is rejected with the operand's textual type included. This protects against treating arbitrary values as addresses.

Source

Thrown at pkg/proc/eval.go:2308

		return
	case reflect.Ptr:
		if xev.Flags&VariableCPtr != 0 {
			stack.pushErr(xev.reslice(low, high, op.TrustLen))
			return
		}
		fallthrough
	default:
		stack.err = fmt.Errorf("can not slice %q (type %s)", astutil.ExprToString(op.Node.X), xev.TypeString())
		return
	}
}

// Evaluates a pointer dereference expression: *<subexpr>
func (scope *EvalScope) evalPointerDeref(op *evalop.PointerDeref, stack *evalStack) {
	xev := stack.pop()

	if xev.Kind != reflect.Ptr {
		stack.err = fmt.Errorf("expression %q (%s) can not be dereferenced", astutil.ExprToString(op.Node.X), xev.TypeString())
		return
	}

	if xev == nilVariable {
		stack.err = errors.New("nil can not be dereferenced")
		return
	}

	if len(xev.Children) == 1 {
		// this branch is here to support pointers constructed with typecasts from ints
		xev.Children[0].OnlyAddr = false
		stack.push(&(xev.Children[0]))
		return
	}
	xev.loadPtr()
	if xev.Unreadable != nil {
		val, ok := constant.Uint64Val(xev.Value)
		if ok && val == 0 {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Print the operand (`print x`) and confirm its type; only evaluate `*x` when x is a pointer.
  2. If you need the value, drop the `*` — evaluate `x` directly.
  3. If x is an interface wrapping a pointer, inspect `x` first; Delve usually shows the concrete value without explicit dereference.
  4. Check the variable's declaration in the source to confirm it is `*T` not `T`.

Example fix

// before (count is an int)
(dlv) print *count
expression "*count" (int) can not be dereferenced

// after
(dlv) print count // plain value
(dlv) print *countPtr // only when the operand is *T
Defensive patterns

Strategy: type-guard

Validate before calling

// Before dereferencing at the prompt:
(dlv) print x  // output shows the type; only *T values can be dereferenced

Type guard

func isPointer(v interface{}) bool {
    return reflect.TypeOf(v).Kind() == reflect.Ptr
}

Prevention

When it happens

Trigger: Evaluating `*x` in the debugger where x is not a pointer — e.g. `*count` where count is an int, `*s` where s is a string, or `*p` where p is a struct value rather than a pointer to one. Also occurs when the operand resolved to an interface's dynamic value that isn't a pointer.

Common situations: Habitual C-style coding in the dlv prompt on non-pointer variables, dereferencing the wrong variable after a rename, forgetting that a function returned a value (not a pointer), or an interface variable holding a non-pointer concrete value.

Related errors


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