{"record":{"id":"eb06376d0938f10d","repo":"go-delve/delve","slug":"can-not-assign-to-t-q-v","errorCode":null,"errorMessage":"can not assign to %T.%q: %v","messagePattern":"can not assign to %T\\.%q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/terminal/starbind/conv.go","lineNumber":197,"sourceCode":"\tr := v.v.FieldByName(name)\n\tif !r.IsValid() {\n\t\treturn starlark.None, starlark.NoSuchAttrError(fmt.Sprintf(\"no field named %q in %T\", name, v.v.Interface()))\n\t}\n\treturn v.env.interfaceToStarlarkValue(r), nil\n}\n\nfunc (v structAsStarlarkValue) SetField(name string, value starlark.Value) (err error) {\n\tdefer func() {\n\t\t// reflect.Value.SetInt, SetFloat, etc panic\n\t\tierr := recover()\n\t\tif ierr == nil {\n\t\t\treturn\n\t\t}\n\t\terr, _ = ierr.(error)\n\t\tif err == nil {\n\t\t\tpanic(ierr)\n\t\t}\n\t\terr = fmt.Errorf(\"can not assign to %T.%q: %v\", v.v.Interface(), name, err)\n\t}()\n\tif r, err := v.valueAttr(name); err != nil || r != nil {\n\t\treturn starlark.NoSuchAttrError(fmt.Sprintf(\"no field named %s in %T\", name, v.v.Interface()))\n\t}\n\tr := v.v.FieldByName(name)\n\tif !r.IsValid() {\n\t\treturn starlark.NoSuchAttrError(fmt.Sprintf(\"no field named %q in %T\", name, v.v.Interface()))\n\t}\n\tswitch value := value.(type) {\n\tcase starlark.Int:\n\t\tn, ok := value.Int64()\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"can not assign big integer to %T.%q\", v.v.Interface(), name)\n\t\t}\n\t\tr.SetInt(n)\n\tcase starlark.Float:\n\t\tr.SetFloat(float64(value))\n\tcase starlark.String:","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/terminal/starbind/conv.go#L179-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"Scripts written against an older Delve API that renamed/removed a field, or attempts to set computed/read-only fields like Variable.Value directly.","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"],"exampleFix":"# before\nbp.Variable.Value = \"x\"   # read-only field -> can not assign\n# after\nbp.Variable = api.Variable{Name: \"x\"}  # assign via a settable field","handlingStrategy":"try-catch","validationCode":"# only assign fields known to be exported and settable\nassert field_name in settable_fields_of(obj), \"field not assignable: \" + field_name","typeGuard":"def is_assignable_field(v, name):\n    f = v.v.Type().FieldByName(name)\n    return f is not None and f.IsExported()","tryCatchPattern":"try:\n    obj.field = value\nexcept Exception as e:\n    if \"can not assign to\" in str(e):\n        # fall back to the dedicated API for this field\n        set_field_via_api(obj, \"field\", value)\n    else:\n        raise","preventionTips":["Only assign exported, documented fields","Never assign read-only computed fields like Variable.Value directly","Keep scripts in sync with Delve API version changes"],"tags":["starlark","delve","scripting","reflection"],"backgroundTag":"starlark-field-assignment-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}