go-delve/delve · error

can not set variables of type %s (not implemented)

Error message

can not set variables of type %s (not implemented)

What it means

setValue falls back to byte-by-byte copy only when the source variable is addressable (srcv.Addr != 0). If none of the special cases (numerics, strings, slices, nil, pointers, copy) apply and the source has no address, the assignment is not implemented for this kind and this error is returned. It signals an unsupported assignment shape rather than invalid input.

Source

Thrown at pkg/proc/eval.go:692

	}

	// slice assignment (this is not handled by the writeCopy below so that
	// results of a reslice operation can be used here).
	if srcv.Kind == reflect.Slice {
		return dstv.writeSlice(srcv.Len, srcv.Cap, srcv.Base)
	}

	// allow any integer to be converted to any pointer
	if t, isptr := dstv.RealType.(*godwarf.PtrType); isptr {
		return dstv.writeUint(srcv.Children[0].Addr, t.ByteSize)
	}

	// byte-by-byte copying for everything else, but the source must be addressable
	if srcv.Addr != 0 {
		return dstv.writeCopy(srcv)
	}

	return fmt.Errorf("can not set variables of type %s (not implemented)", dstv.Kind.String())
}

// SetVariable sets the value of the named variable
func (scope *EvalScope) SetVariable(name, value string) error {
	ops, err := evalop.CompileSet(scopeToEvalLookup{scope}, name, value, scope.evalopFlags())
	if err != nil {
		return err
	}

	stack := &evalStack{}
	stack.eval(scope, ops)
	_, err = stack.result(nil)
	return err
}

// LocalVariables returns all local variables from the current function scope.
func (scope *EvalScope) LocalVariables(cfg LoadConfig) ([]*Variable, error) {
	vars, err := scope.Locals(0, "")

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Assign a value that lives in memory: first store the source into an addressable variable (e.g. a temporary global or an existing variable) and copy from it.
  2. Break composite assignments into per-field assignments: set each field of the struct individually.
  3. For call injection, pass addressable arguments (variables) rather than composite literal expressions.
  4. If a kind you believe should work triggers this, it may warrant an upstream feature request; meanwhile compute the value in the debuggee via a call injection (e.g. inject a setter function).

Example fix

// before
scope.SetVariable("s", "struct{T int}{T: 42}") // can not set variables of type struct (not implemented)
// after
scope.SetVariable("s.T", "42") // assign fields individually
Defensive patterns

Strategy: validation

Validate before calling

src, err := scope.EvalExpression(value, loadSingleValue)
if err != nil { return err }
if src.Addr == 0 && src.Kind != reflect.Basic {
    return fmt.Errorf("value %q is non-addressable of kind %s; assign fields or an addressable variable instead", value, src.Kind)
}

Type guard

func isAddressable(v *proc.Variable) bool { return v != nil && v.Addr != 0 }

Try / catch

if err := scope.SetVariable(name, value); err != nil {
    if strings.Contains(err.Error(), "not implemented") {
        return fmt.Errorf("assignment of %q unsupported for kind reported; assign per-field instead", value)
    }
    return err
}

Prevention

When it happens

Trigger: SetVariable or call-injection argument copy where the source value is a non-addressable constant/intermediate result of a kind not handled by the numeric/string/slice/pointer fast paths (dstv.Kind reported in the message, e.g. struct, chan, map, interface), so writeCopy cannot be used.

Common situations: Assigning a literal struct or composite expression to a struct variable; assigning the result of an expression (e.g. `x = <-ch`, `x = someFunc()` for chan/struct kinds); copying from a register-resident optimized value with no memory address; call injection passing a temporary struct constant as an argument.

Related errors


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