{"record":{"id":"2223f0ad0cab0e7d","repo":"go-delve/delve","slug":"map-index-out-of-bounds","errorCode":null,"errorMessage":"map index out of bounds","messagePattern":"map index out of bounds","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/eval.go","lineNumber":2286,"sourceCode":"\t}\n\n\tswitch xev.Kind {\n\tcase reflect.Slice, reflect.Array, reflect.String:\n\t\tif xev.Base == 0 {\n\t\t\tstack.err = fmt.Errorf(\"can not slice %q\", astutil.ExprToString(op.Node.X))\n\t\t\treturn\n\t\t}\n\t\tstack.pushErr(xev.reslice(low, high, op.TrustLen))\n\t\treturn\n\tcase reflect.Map:\n\t\tif op.Node.High != nil {\n\t\t\tstack.err = errors.New(\"second slice argument must be empty for maps\")\n\t\t\treturn\n\t\t}\n\t\txev.mapSkip += int(low)\n\t\txev.mapIterator(0) // reads map length\n\t\tif int64(xev.mapSkip) >= xev.Len {\n\t\t\tstack.err = errors.New(\"map index out of bounds\")\n\t\t\treturn\n\t\t}\n\t\tstack.push(xev)\n\t\treturn\n\tcase reflect.Ptr:\n\t\tif xev.Flags&VariableCPtr != 0 {\n\t\t\tstack.pushErr(xev.reslice(low, high, op.TrustLen))\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tdefault:\n\t\tstack.err = fmt.Errorf(\"can not slice %q (type %s)\", astutil.ExprToString(op.Node.X), xev.TypeString())\n\t\treturn\n\t}\n}\n\n// Evaluates a pointer dereference expression: *<subexpr>\nfunc (scope *EvalScope) evalPointerDeref(op *evalop.PointerDeref, stack *evalStack) {","sourceCodeStart":2268,"sourceCodeEnd":2304,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/eval.go#L2268-L2304","documentation":"For map reslices, delve adds the low bound to an internal skip counter (mapSkip) and reads the map's length; if the skip count is >= the map length there are no entries to return, so this error is thrown. Unlike Go slices (which clamp), map 'slicing' in the debugger is bounds-checked.","triggerScenarios":"Evaluating m[n:] where n is greater than or equal to len(m); reslicing an empty map (m[0:]); using a stale length assumption after the map shrank between stops.","commonSituations":"Inspecting a map believed to be populated but actually empty; scripting that slices m[k:] with a computed k exceeding the live map size; skipping past all entries expecting remaining items.","solutions":["Check len(m) first (print len(m)) and use a low bound smaller than the length.","Use m[0:] or m[0:0] to view the map from the start.","If the map should be non-empty, verify the program state — the map may have been drained or never populated; set a breakpoint where it is built.","In tooling, guard reslice requests: only issue map reslice when requested low < variable.Len."],"exampleFix":"// before\nprint m[10:] // m has 3 entries\n// after\nprint m[0:]  // or check len(m) first","handlingStrategy":"validation","validationCode":"mv, err := scope.EvalExpression(mapExpr, cfg)\nif err != nil { return err }\nif low >= int(mv.Len) {\n    return fmt.Errorf(\"skip %d exceeds map length %d\", low, mv.Len)\n}","typeGuard":"func mapSkipInRange(mv *proc.Variable, low int) bool {\n    return mv != nil && mv.Kind == reflect.Map && int64(low) < mv.Len\n}","tryCatchPattern":"_, err := scope.EvalExpression(expr, cfg)\nif err != nil && strings.Contains(err.Error(), \"map index out of bounds\") {\n    return fmt.Errorf(\"skip index exceeds len(map); use %s[0:]\", mapExpr)\n}","preventionTips":["Check len(m) before reslicing with a skip count","Default to m[0:] or m[0:0] for map inspection","Re-read the variable at the current stop rather than caching stale lengths","Clamp computed skip values to Len-1 in tooling"],"tags":["go","debugger","map","out-of-bounds"],"backgroundTag":"index-out-of-range","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}