{"record":{"id":"de395df57e423b23","repo":"go-delve/delve","slug":"no-return-values","errorCode":null,"errorMessage":"no return values","messagePattern":"no return values","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"pkg/proc/fncall.go","lineNumber":431,"sourceCode":"\t\t} else {\n\t\t\tfncallLog(\"additional fncall error: %v\", fncall.err)\n\t\t}\n\t\treturn\n\t}\n\n\tif fncall.panicvar != nil {\n\t\tif stack.err == nil {\n\t\t\tstack.err = fncallPanicErr{fncall.panicvar}\n\t\t} else {\n\t\t\tfncallLog(\"additional fncall panic: %v\", fncall.panicvar)\n\t\t}\n\t\treturn\n\t}\n\tswitch len(fncall.retvars) {\n\tcase 0:\n\t\tr := newVariable(\"\", 0, nil, scope.BinInfo, nil)\n\t\tr.loaded = true\n\t\tr.Unreadable = errors.New(\"no return values\")\n\t\tstack.push(r)\n\tcase 1:\n\t\tstack.push(fncall.retvars[0])\n\tdefault:\n\t\t// create a fake variable without address or type to return multiple values\n\t\tr := newVariable(\"\", 0, nil, scope.BinInfo, nil)\n\t\tr.loaded = true\n\t\tr.Children = make([]Variable, len(fncall.retvars))\n\t\tfor i := range fncall.retvars {\n\t\t\tr.Children[i] = *fncall.retvars[i]\n\t\t}\n\t\tstack.push(r)\n\t}\n}\n\n// fncallPanicErr is the error returned if a called function panics\ntype fncallPanicErr struct {\n\tpanicVar *Variable","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/fncall.go#L413-L449","documentation":"After an injected function call completes, Delve builds the call's result from the recorded return variables. If the finished function has zero return values, Delve cannot produce a result variable and marks the result unreadable with \"no return values\". This surfaces to users who call a void function and expect a printed return value.","triggerScenarios":"Using `call f()` where f has no return values and then inspecting/pushing the call result (e.g. `call` on a void function whose result expression expects a value).","commonSituations":"Calling a void helper and trying to use its result; confusing print/call semantics for void functions; wrappers around procedures.","solutions":["Treat the call as side-effect only; the target state was changed, no value is returned","Add return values to the called function if you need a result","Use `print f(...)` only for functions that return values; for void functions observe the affected variables after the call"],"exampleFix":"// before\n(dlv) call doSetup() // void; no return values\n// after: inspect effects instead\n(dlv) print cfg\ndlv) call doSetup()","handlingStrategy":"fallback","validationCode":"// only capture results from functions with return values\n// check arity first:\n// (dlv) print f // 0 results -> treat call as side-effect only","typeGuard":null,"tryCatchPattern":"stack := scope.CallFunction(expr)\nif rv := stack.Pop(); rv != nil && rv.Unreadable != nil && rv.Unreadable.Error() == \"no return values\" {\n    // no result expected; observe affected variables instead\n}","preventionTips":["Treat void function calls as side-effect-only","Inspect the variables the call should have modified","Add return values if a result is genuinely needed","Use print only for functions that return values"],"tags":["debugger","function-call-injection","return-values"],"backgroundTag":"no-return-values","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}