{"record":{"id":"cf668ba14a25486d","repo":"go-delve/delve","slug":"channel-filter-without-eval-scope","errorCode":null,"errorMessage":"channel filter without eval scope","messagePattern":"channel filter without eval scope","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/rpc2/server.go","lineNumber":711,"sourceCode":"\t//TODO(aarzilli): if arg contains a running goroutines filter (not negated)\n\t// and start == 0 and count == 0 then we can optimize this by just looking\n\t// at threads directly.\n\n\tvar gs []*proc.G\n\tvar nextg int\n\tvar err error\n\tvar gsLoaded bool\n\n\tfor _, filter := range arg.Filters {\n\t\tif filter.Kind == api.GoroutineWaitingOnChannel {\n\t\t\tif filter.Negated {\n\t\t\t\treturn errors.New(\"channel filter can not be negated\")\n\t\t\t}\n\t\t\tif arg.Count == 0 {\n\t\t\t\treturn errors.New(\"count == 0 not allowed with a channel filter\")\n\t\t\t}\n\t\t\tif arg.EvalScope == nil {\n\t\t\t\treturn errors.New(\"channel filter without eval scope\")\n\t\t\t}\n\t\t\tgs, err = s.debugger.ChanGoroutines(arg.EvalScope.GoroutineID, arg.EvalScope.Frame, arg.EvalScope.DeferredCall, filter.Arg, arg.Start, arg.Count)\n\t\t\tif len(gs) == arg.Count {\n\t\t\t\tnextg = arg.Start + len(gs)\n\t\t\t} else {\n\t\t\t\tnextg = -1\n\t\t\t}\n\t\t\tgsLoaded = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !gsLoaded {\n\t\tgs, nextg, err = s.debugger.Goroutines(arg.Start, arg.Count)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/rpc2/server.go#L693-L729","documentation":"A channel filter needs an EvalScope because the filter's Arg is evaluated as a channel expression in the scope of a specific goroutine/frame. Without EvalScope there is no context in which to evaluate the channel argument, so the request is rejected.","triggerScenarios":"ListGoroutines RPC with a GoroutineWaitingOnChannel filter but arg.EvalScope == nil (or omitted).","commonSituations":"Custom RPC clients or scripts that pass filters but never set EvalScope; UI code that only sets EvalScope for variable evaluation but not goroutine listing.","solutions":["Provide EvalScope with at least GoroutineID and Frame set (usually current goroutine, frame 0).","Resolve the channel address first via variable evaluation, then pass scope + Arg.","Skip the channel filter if no scope is available."],"exampleFix":"// before\nin := api.ListGoroutinesIn{Count: 100, Filters: channelFilters}\n// after\nin := api.ListGoroutinesIn{Count: 100, Filters: channelFilters, EvalScope: &api.EvalScope{GoroutineID: -1, Frame: 0}}","handlingStrategy":"validation","validationCode":"if hasChannelFilter(filters) && in.EvalScope == nil {\n    in.EvalScope = &api.EvalScope{GoroutineID: -1, Frame: 0}\n}","typeGuard":null,"tryCatchPattern":"err := client.Call(\"RPCServer.ListGoroutines\", in, &out)\nif err != nil && strings.Contains(err.Error(), \"without eval scope\") {\n    in.EvalScope = &api.EvalScope{GoroutineID: -1, Frame: 0}\n    err = client.Call(\"RPCServer.ListGoroutines\", in, &out)\n}","preventionTips":["Always attach an EvalScope when using expression-based filters.","Use the currently selected goroutine/frame from your UI state.","Centralize request building so EvalScope is never forgotten."],"tags":["go","rpc","goroutines","evalscope","validation"],"backgroundTag":"missing-eval-scope","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}