go-delve/delve · error

bad channel type

Error message

bad channel type

What it means

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.

Source

Thrown at pkg/proc/variables.go:1676

		}
	}

	if v.Addr == fakeAddressUnresolv && v.fieldType == nil {
		return
	}

	v.stride = v.fieldType.Size()
	if t, ok := v.fieldType.(*godwarf.PtrType); ok {
		v.stride = t.ByteSize
	}
}

// loadChanInfo loads the buffer size of the channel and changes the type of
// the buf field from unsafe.Pointer to an array of the correct type.
func (v *Variable) loadChanInfo() {
	chanType, ok := v.RealType.(*godwarf.ChanType)
	if !ok {
		v.Unreadable = errors.New("bad channel type")
		return
	}
	sv := v.clone()
	sv.RealType = godwarf.ResolveTypedef(&(chanType.TypedefType))
	sv = sv.maybeDereference()
	if sv.Unreadable != nil || sv.Addr == 0 {
		return
	}
	v.Base = sv.Addr
	structType, ok := sv.DwarfType.(*godwarf.StructType)
	if !ok {
		v.Unreadable = errors.New("bad channel type")
		return
	}

	lenAddr, _ := sv.toField(structType.Field[1])
	lenAddr.loadValue(loadSingleValue)
	if lenAddr.Unreadable != nil {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Print the variable's type in the debugger (e.g. `print` the value) and confirm it is really a channel.
  2. Resolve typedefs: check that your Go build emits complete DWARF (no -ldflags="-s -w").
  3. Upgrade delve; older versions had type-resolution bugs on chan typedefs.
  4. If hit via an API client, request the variable with its exact DWARF type rather than an inferred one.

Example fix

// before (client assumes it is a chan)
ch := eval("v")
printChanBuffer(ch)
// after (guard on actual type)
ch := eval("v")
if ch.Type == "chan ..." { printChanBuffer(ch) } else { fmt.Println(ch.Type) }
Defensive patterns

Strategy: type-guard

Validate before calling

if ct, ok := v.RealType.(*godwarf.ChanType); ok {
    // safe to call loadChanInfo path
    _ = ct
}

Type guard

func isChanVariable(v *Variable) bool {
    _, ok := v.RealType.(*godwarf.ChanType)
    return ok
}

Try / catch

if v.Unreadable != nil {
    if strings.Contains(v.Unreadable.Error(), "bad channel type") {
        // print as generic value instead of channel introspection
        return
    }
    return v.Unreadable
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/3733908ba06d32f9. Report an issue: GitHub.