go-delve/delve · warning

key not found

Error message

key not found

What it means

When evaluating a map index expression m[k], Delve looks up k among the loaded map entries. Go would return the zero value for a missing key, but Delve cannot fabricate zero values of arbitrary types from debug info, so instead of returning a zero it throws 'key not found' when the key is absent from the map (or from the loaded entries).

Source

Thrown at pkg/proc/eval.go:2924

		if first {
			first = false
			if err := idx.isType(key.RealType, key.Kind); err != nil {
				return nil, err
			}
		}
		eql, err := compareOp(token.EQL, key, idx)
		if err != nil {
			return nil, err
		}
		if eql {
			return it.value(), nil
		}
	}
	if v.Unreadable != nil {
		return nil, v.Unreadable
	}
	// go would return zero for the map value type here, we do not have the ability to create zeroes
	return nil, errors.New("key not found")
}

// LoadResliced returns a new array, slice or map that starts at index start and contains
// up to cfg.MaxArrayValues children.
func (v *Variable) LoadResliced(start int, cfg LoadConfig) (newV *Variable, err error) {
	switch v.Kind {
	case reflect.Array, reflect.Slice:
		low, high := int64(start), int64(start+cfg.MaxArrayValues)
		if high > v.Len {
			high = v.Len
		}
		newV, err = v.reslice(low, high, false)
		if err != nil {
			return nil, err
		}
	case reflect.Map:
		newV = v.clone()
		newV.Children = nil

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Verify the key exists: iterate/inspect the map with 'print m' (careful with large maps) or check 'print len(m)'
  2. Check membership via the program's logic instead: set a breakpoint where the code does v, ok := m[k] and inspect ok
  3. If the map is large, raise 'config max-array-values' so the key's entry gets loaded, then retry the lookup
  4. Confirm the key literal type matches the map key type (e.g. use 'print m[42]' not 'print m["42"]' for int keys)

Example fix

// before (dlv CLI)
(dlv) print userMap["alice"]   // key absent -> error

// after
(dlv) print userMap            // inspect actual keys
(dlv) print userMap["bob"]     // use an existing key
Defensive patterns

Strategy: fallback

Validate before calling

// before a map lookup in dlv, confirm the key exists by inspecting entries
(dlv) print m               // small maps only
(dlv) print len(m)
// or check membership at a breakpoint where the code does v, ok := m[k]

Type guard

func mapHasKey(keys []string, k string) bool {
    for _, key := range keys { if key == k { return true } }
    return false
}

Try / catch

// RPC client pattern
val, err := client.EvalVariable(scope, "m[\"key\"]", cfg)
if err != nil && strings.Contains(err.Error(), "key not found") {
    // treat as missing key: use the zero value of the map's value type
    fmt.Println("key absent in debuggee map")
}

Prevention

When it happens

Trigger: Evaluating 'print m["missing"]' or 'print m[someKey]' where the key does not exist in the map, or exists but was not among the loaded entries (map larger than MaxArrayValues, or mapSkip/LoadResliced windowing).

Common situations: Probing whether a map contains a key during debugging; inspecting a large map where the desired key falls outside the first N loaded entries; typo'd or type-mismatched key literals (e.g. int vs string).

Related errors


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