go-delve/delve · error
can not assign to %T.%q: %v
Error message
can not assign to %T.%q: %v
What it means
In starbind (Starlark scripting), assigning to an attribute of a Go struct wrapped as a Starlark value failed: the deferred recover caught an error/panic from the reflect-based SetField path and re-wraps it. It means the field cannot be assigned, e.g. the field is unexported or the value type mismatches the field type.
Source
Thrown at pkg/terminal/starbind/conv.go:197
r := v.v.FieldByName(name)
if !r.IsValid() {
return starlark.None, starlark.NoSuchAttrError(fmt.Sprintf("no field named %q in %T", name, v.v.Interface()))
}
return v.env.interfaceToStarlarkValue(r), nil
}
func (v structAsStarlarkValue) SetField(name string, value starlark.Value) (err error) {
defer func() {
// reflect.Value.SetInt, SetFloat, etc panic
ierr := recover()
if ierr == nil {
return
}
err, _ = ierr.(error)
if err == nil {
panic(ierr)
}
err = fmt.Errorf("can not assign to %T.%q: %v", v.v.Interface(), name, err)
}()
if r, err := v.valueAttr(name); err != nil || r != nil {
return starlark.NoSuchAttrError(fmt.Sprintf("no field named %s in %T", name, v.v.Interface()))
}
r := v.v.FieldByName(name)
if !r.IsValid() {
return starlark.NoSuchAttrError(fmt.Sprintf("no field named %q in %T", name, v.v.Interface()))
}
switch value := value.(type) {
case starlark.Int:
n, ok := value.Int64()
if !ok {
return fmt.Errorf("can not assign big integer to %T.%q", v.v.Interface(), name)
}
r.SetInt(n)
case starlark.Float:
r.SetFloat(float64(value))
case starlark.String:View on GitHub (pinned to a23773e6c3)
Solutions
- Check the field name spelling and that it exists in the current Delve API
- Only assign exported, mutable struct fields from Starlark
- Convert the value to the field's Go type (e.g. starlark.String vs int field)
- Use the dedicated API function for read-only fields instead of direct assignment
Example fix
# before
bp.Variable.Value = "x" # read-only field -> can not assign
# after
bp.Variable = api.Variable{Name: "x"} # assign via a settable field Defensive patterns
Strategy: try-catch
Validate before calling
# only assign fields known to be exported and settable assert field_name in settable_fields_of(obj), "field not assignable: " + field_name
Type guard
def is_assignable_field(v, name):
f = v.v.Type().FieldByName(name)
return f is not None and f.IsExported() Try / catch
try:
obj.field = value
except Exception as e:
if "can not assign to" in str(e):
# fall back to the dedicated API for this field
set_field_via_api(obj, "field", value)
else:
raise Prevention
- Only assign exported, documented fields
- Never assign read-only computed fields like Variable.Value directly
- Keep scripts in sync with Delve API version changes
When it happens
Trigger: A Starlark script executes `obj.field = value` on a wrapped Go struct where the underlying reflect Set call panics or errors (unexported field, wrong type), and valueAttr did not intercept the name.
Common situations: Scripts written against an older Delve API that renamed/removed a field, or attempts to set computed/read-only fields like Variable.Value directly.
Related errors
- error setting argument %q to %s: %v
- can not assign big integer to %T.%q
- can not assign value of type %T to %T.%q
- key type not supported %T
- error setting argument %q: can not convert %s to %s: %s
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/eb06376d0938f10d.
Report an issue: GitHub.