go-delve/delve · error

invalid argument %s (type %s) to real

Error message

invalid argument %s (type %s) to real

What it means

Delve's `real()` builtin accepts only values that evaluate to integer, float or complex constants. This error fires when the argument's loaded value is nil (unreadable) or of another constant kind (string, bool), including the argument's source text and type in the message.

Source

Thrown at pkg/proc/eval.go:2048

	}

	return newConstant(constant.Imag(arg.Value), arg.bi, arg.mem), nil
}

func realBuiltin(args []*Variable, nodeargs []ast.Expr) (*Variable, error) {
	if len(args) != 1 {
		return nil, fmt.Errorf("wrong number of arguments to real: %d", len(args))
	}

	arg := args[0]
	arg.loadValue(loadSingleValue)

	if arg.Unreadable != nil {
		return nil, arg.Unreadable
	}

	if arg.Value == nil || ((arg.Value.Kind() != constant.Int) && (arg.Value.Kind() != constant.Float) && (arg.Value.Kind() != constant.Complex)) {
		return nil, fmt.Errorf("invalid argument %s (type %s) to real", astutil.ExprToString(nodeargs[0]), arg.TypeString())
	}

	return newConstant(constant.Real(arg.Value), arg.bi, arg.mem), nil
}

func minBuiltin(args []*Variable, nodeargs []ast.Expr) (*Variable, error) {
	return minmaxBuiltin("min", token.LSS, args, nodeargs)
}

func maxBuiltin(args []*Variable, nodeargs []ast.Expr) (*Variable, error) {
	return minmaxBuiltin("max", token.GTR, args, nodeargs)
}

func minmaxBuiltin(name string, op token.Token, args []*Variable, nodeargs []ast.Expr) (*Variable, error) {
	var best *Variable

	for i := range args {
		if args[i].Kind == reflect.String {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Pass a numeric (int/float/complex) typed expression; check with `ptype <expr>`.
  2. Print the variable by itself first to confirm its value is readable, not optimized out.
  3. For strings/bools, real() is meaningless — drop the call or fix the variable.
  4. If the value is an interface, evaluate the concrete numeric field or assert its type first.

Example fix

// before
real(flag)       // flag is bool
// after
real(c)          // c is complex128/float/int
Defensive patterns

Strategy: type-guard

Validate before calling

// before evaluating real(x)
v, err := evalLoad(x)
if err != nil || v.Value == nil ||
    (v.Value.Kind() != constant.Int && v.Value.Kind() != constant.Float && v.Value.Kind() != constant.Complex) {
    return fmt.Errorf("real requires int/float/complex, got %s", v.TypeString())
}

Type guard

func isRealable(v *proc.Variable) bool {
    if v.Unreadable != nil || v.Value == nil {
        return false
    }
    k := v.Value.Kind()
    return k == constant.Int || k == constant.Float || k == constant.Complex
}

Try / catch

val, err := evalReal(expr)
if err != nil && strings.Contains(err.Error(), "invalid argument") {
    // print the variable directly and check its type/value before retrying
}

Prevention

When it happens

Trigger: Evaluating `real(x)` where x's constant value is a string or bool, or where arg.Value == nil because the memory read / value load failed (eval.go:2048, realBuiltin).

Common situations: Calling real on a string or boolean variable, on a variable that was optimized out and could not be loaded, or on an interface value that resolved to a non-numeric concrete type.

Related errors


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