{"record":{"id":"c4b30931dfd13ea1","repo":"go-delve/delve","slug":"can-not-assign-to-function-expression","errorCode":null,"errorMessage":"can not assign to function expression","messagePattern":"can not assign to function expression","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/eval.go","lineNumber":660,"sourceCode":"\t\treturn dstv.writeFloatRaw(f, dstv.RealType.Size())\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tn, _ := constant.Int64Val(srcv.Value)\n\t\treturn dstv.writeUint(uint64(n), dstv.RealType.Size())\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\tn, _ := constant.Uint64Val(srcv.Value)\n\t\treturn dstv.writeUint(n, dstv.RealType.Size())\n\tcase reflect.Bool:\n\t\treturn dstv.writeBool(constant.BoolVal(srcv.Value))\n\tcase reflect.Complex64, reflect.Complex128:\n\t\treal, _ := constant.Float64Val(constant.Real(srcv.Value))\n\t\timag, _ := constant.Float64Val(constant.Imag(srcv.Value))\n\t\treturn dstv.writeComplex(real, imag, dstv.RealType.Size())\n\tcase reflect.Func:\n\t\tif dstv.RealType.Size() == 0 {\n\t\t\tif dstv.Name != \"\" {\n\t\t\t\treturn fmt.Errorf(\"can not assign to %s\", dstv.Name)\n\t\t\t}\n\t\t\treturn errors.New(\"can not assign to function expression\")\n\t\t}\n\t}\n\n\t// nilling nillable variables\n\tif srcv == nilVariable {\n\t\treturn dstv.writeZero()\n\t}\n\n\tif srcv.Kind == reflect.String {\n\t\tif srcv.Base == 0 && srcv.Len > 0 && srcv.Flags&VariableConstant != 0 {\n\t\t\treturn errFuncCallNotAllowedStrAlloc\n\t\t}\n\t\treturn dstv.writeString(uint64(srcv.Len), srcv.Base)\n\t}\n\n\t// slice assignment (this is not handled by the writeCopy below so that\n\t// results of a reslice operation can be used here).\n\tif srcv.Kind == reflect.Slice {","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/eval.go#L642-L678","documentation":"setValue's assignment path rejects targets whose real type is reflect.Func: function values are not assignable memory in Go, so delve refuses. If the target variable has a name it reports 'can not assign to <name>'; an anonymous/intermediate function-typed expression yields this generic message. Thrown during SetVariable and during function-call argument copying (funcCallCopyOneArg).","triggerScenarios":"Attempting `set f = someFunc` where f is a func; passing a function value as an argument to an injected function call (funcCallCopyOneArg) via EvalExpressionWithCalls; assigning to an expression that resolves to a func type.","commonSituations":"Trying to monkey-patch a callback/handler variable in a debug session; injecting a call like replaceHandler(myFunc) where the parameter is a func; RPC clients building SetVariable commands on function-typed fields.","solutions":["Do not assign func values; instead set an interface/bool flag the program checks, or use a breakpoint with a condition to alter control flow.","Pass a pointer or an index/enum value the callee can dispatch on, instead of the function itself.","If the goal is calling a function, use delve's function injection with non-func arguments only.","Validate the target variable's Kind before issuing set: if Kind == reflect.Func, surface a friendly error in your tooling."],"exampleFix":"// before\ndbg.SetVariable(\"handler\", \"myHandler\") // handler is func\n// after\n// set a flag or interface field instead:\ndbg.SetVariable(\"useHandlerV2\", \"true\")","handlingStrategy":"validation","validationCode":"v, err := scope.EvalExpression(targetExpr, cfg)\nif err == nil && v.Kind == reflect.Func {\n    return fmt.Errorf(\"%s is a function and cannot be assigned\", targetExpr)\n}","typeGuard":"func isAssignable(v *proc.Variable) bool {\n    return v != nil && v.Kind != reflect.Func\n}","tryCatchPattern":"err := scope.SetValue(target, srcv)\nif err != nil && strings.Contains(err.Error(), \"can not assign\") {\n    return fmt.Errorf(\"delve cannot assign function values; mutate a flag/interface instead\")\n}","preventionTips":["Never issue set on func-typed variables or pass funcs to injected calls","Check variable Kind before SetValue in tooling","Use flags, interfaces, or pointers to change program behavior instead of swapping funcs","Document function injection argument restrictions for RPC clients"],"tags":["go","debugger","assignment","function-values"],"backgroundTag":"unassignable-target","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}