{"record":{"id":"3733908ba06d32f9","repo":"go-delve/delve","slug":"bad-channel-type","errorCode":null,"errorMessage":"bad channel type","messagePattern":"bad channel type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/variables.go","lineNumber":1676,"sourceCode":"\t\t}\n\t}\n\n\tif v.Addr == fakeAddressUnresolv && v.fieldType == nil {\n\t\treturn\n\t}\n\n\tv.stride = v.fieldType.Size()\n\tif t, ok := v.fieldType.(*godwarf.PtrType); ok {\n\t\tv.stride = t.ByteSize\n\t}\n}\n\n// loadChanInfo loads the buffer size of the channel and changes the type of\n// the buf field from unsafe.Pointer to an array of the correct type.\nfunc (v *Variable) loadChanInfo() {\n\tchanType, ok := v.RealType.(*godwarf.ChanType)\n\tif !ok {\n\t\tv.Unreadable = errors.New(\"bad channel type\")\n\t\treturn\n\t}\n\tsv := v.clone()\n\tsv.RealType = godwarf.ResolveTypedef(&(chanType.TypedefType))\n\tsv = sv.maybeDereference()\n\tif sv.Unreadable != nil || sv.Addr == 0 {\n\t\treturn\n\t}\n\tv.Base = sv.Addr\n\tstructType, ok := sv.DwarfType.(*godwarf.StructType)\n\tif !ok {\n\t\tv.Unreadable = errors.New(\"bad channel type\")\n\t\treturn\n\t}\n\n\tlenAddr, _ := sv.toField(structType.Field[1])\n\tlenAddr.loadValue(loadSingleValue)\n\tif lenAddr.Unreadable != nil {","sourceCodeStart":1658,"sourceCodeEnd":1694,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/variables.go#L1658-L1694","documentation":"loadChanInfo computes a channel's buffer size by downcasting the variable's RealType to *godwarf.ChanType. When the runtime type of the value is not actually a channel type, the variable is marked unreadable with this error. It is a sanity check guarding the channel-buffer introspection path.","triggerScenarios":"Evaluating or printing a variable whose type claim says channel (or whose loadValue path invokes loadChanInfo) but whose resolved RealType is not *godwarf.ChanType — e.g. a typedef/interface wrapper that resolved incorrectly, or corrupted memory/type data.","commonSituations":"Debugging optimized binaries where type resolution produces a typedef that fails to resolve to the underlying chan type, evaluating expressions through the DAP/RPC API where the type was guessed, or inspecting values in core dumps with incomplete type info.","solutions":["Print the variable's type in the debugger (e.g. `print` the value) and confirm it is really a channel.","Resolve typedefs: check that your Go build emits complete DWARF (no -ldflags=\"-s -w\").","Upgrade delve; older versions had type-resolution bugs on chan typedefs.","If hit via an API client, request the variable with its exact DWARF type rather than an inferred one."],"exampleFix":"// before (client assumes it is a chan)\nch := eval(\"v\")\nprintChanBuffer(ch)\n// after (guard on actual type)\nch := eval(\"v\")\nif ch.Type == \"chan ...\" { printChanBuffer(ch) } else { fmt.Println(ch.Type) }","handlingStrategy":"type-guard","validationCode":"if ct, ok := v.RealType.(*godwarf.ChanType); ok {\n    // safe to call loadChanInfo path\n    _ = ct\n}","typeGuard":"func isChanVariable(v *Variable) bool {\n    _, ok := v.RealType.(*godwarf.ChanType)\n    return ok\n}","tryCatchPattern":"if v.Unreadable != nil {\n    if strings.Contains(v.Unreadable.Error(), \"bad channel type\") {\n        // print as generic value instead of channel introspection\n        return\n    }\n    return v.Unreadable\n}","preventionTips":["Confirm the variable's type string starts with \"chan\" before channel-specific evaluation","Avoid evaluating values through guessed/inferred types in API clients","Keep delve updated for correct typedef resolution"],"tags":["debugger","channels","types"],"backgroundTag":"bad-channel-type","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}