{"record":{"id":"b47f75a2654701b6","repo":"go-delve/delve","slug":"second-slice-argument-must-be-empty-for-maps","errorCode":null,"errorMessage":"second slice argument must be empty for maps","messagePattern":"second slice argument must be empty for maps","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/eval.go","lineNumber":2280,"sourceCode":"\tif xev.Unreadable != nil {\n\t\tstack.err = xev.Unreadable\n\t\treturn\n\t}\n\tif !op.HasHigh {\n\t\thigh = xev.Len\n\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())","sourceCodeStart":2262,"sourceCodeEnd":2298,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/eval.go#L2262-L2298","documentation":"When reslicing a map expression (evalReslice), delve treats [low:] on a map as 'skip low entries' (a display feature; [0:0] returns the whole map). Providing a high bound on a map is unsupported, so this error is thrown. It is a deliberate restriction of the debugger's map-slicing syntax, not a Go language error.","triggerScenarios":"Evaluating a map expression with a two-index slice like m[1:5] or m[0:10] in print/eval; DAP/RPC clients building reslice operations with High set on a map-typed variable.","commonSituations":"Users typing m[0:10] expecting Go-style slicing (maps are not sliceable in Go either); UIs that generically offer low/high slice inputs for any collection including maps.","solutions":["Use only a low bound for maps: m[5:] to skip the first 5 entries.","Use m[0:0] to request the entire map (delve's documented hack).","If you need a bounded number of entries, rely on the configured max variable string length / max map count instead of a high slice index.","In tooling, check the variable's Kind == reflect.Map and strip the High expression before sending a reslice request."],"exampleFix":"// before\nprint bigMap[0:20]\n// after\nprint bigMap[0:]   // or bigMap[0:0] for the whole map","handlingStrategy":"validation","validationCode":"v, _ := scope.EvalExpression(mapExpr, cfg)\nif v.Kind == reflect.Map && strings.Contains(expr, \":\") {\n    if high, ok := resliceHigh(expr); ok {\n        return fmt.Errorf(\"drop the high bound for maps: %s[%v:]\", mapExpr, resliceLow(expr))\n    }\n}","typeGuard":"func validMapReslice(kind reflect.Kind, hasHigh bool) bool {\n    return kind != reflect.Map || !hasHigh\n}","tryCatchPattern":"_, err := scope.EvalExpression(expr, cfg)\nif err != nil && strings.Contains(err.Error(), \"second slice argument must be empty for maps\") {\n    expr = stripHighBound(expr) // m[a:b] -> m[a:]\n    _, err = scope.EvalExpression(expr, cfg)\n}","preventionTips":["Only use [low:] (no high bound) when slicing map expressions","Use m[0:0] to fetch an entire map in delve","Validate user-supplied slice expressions against the variable's Kind before eval","Never assume Go slice semantics apply to map reslices in the debugger"],"tags":["go","debugger","map","reslice"],"backgroundTag":"invalid-slice-bounds","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}