{"record":{"id":"217beb9a90df1771","repo":"go-delve/delve","slug":"negative-maximum-stack-depth","errorCode":null,"errorMessage":"negative maximum stack depth","messagePattern":"negative maximum stack depth","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/stack.go","lineNumber":438,"sourceCode":"\tif fn != nil && !fn.cu.image.Stripped() && !r.SystemStack && it.g != nil {\n\t\tdwarfTree, _ := fn.cu.image.getDwarfTree(fn.offset)\n\t\tif dwarfTree != nil {\n\t\t\tc := readLocalPtrVar(dwarfTree, goClosurePtr, it.target, it.bi, fn.cu.image, r.Regs, it.mem)\n\t\t\tif c != 0 {\n\t\t\t\tif c >= it.g.stack.lo && c < it.g.stack.hi {\n\t\t\t\t\tr.closurePtr = int64(c) - int64(it.g.stack.hi)\n\t\t\t\t} else {\n\t\t\t\t\tr.closurePtr = int64(c)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn r\n}\n\nfunc (it *stackIterator) stacktrace(depth int, initialFrames []Stackframe) ([]Stackframe, error) {\n\tif depth < 0 {\n\t\treturn nil, errors.New(\"negative maximum stack depth\")\n\t}\n\tvar frames []Stackframe\n\tif len(initialFrames) > 0 {\n\t\tframes = initialFrames\n\t\tif len(frames) >= depth+1 {\n\t\t\treturn frames, nil\n\t\t}\n\t} else {\n\t\tframes = make([]Stackframe, 0, depth+1)\n\t}\n\tf := func(frame Stackframe) bool {\n\t\tframes = append(frames, frame)\n\t\treturn len(frames) < depth+1\n\t}\n\tit.stacktraceFunc(f)\n\tif it.Err() != nil && len(frames) == 1 && it.g != nil && frames[0].SystemStack && (it.opts&StacktraceSimple == 0) {\n\t\t// If we can't continue from the first frame, and it was on a system stack\n\t\t// and we have a goroutine which we are allowed to switch to then switch","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/stack.go#L420-L456","documentation":"stacktrace validates the requested maximum depth and rejects negative values before walking the stack. Callers pass the user-specified depth limit for stack unwinding; a negative number is meaningless and signals a caller bug.","triggerScenarios":"Calling any stack-unwinding API (e.g. Thread/ Goroutine stack requests, depth-parameterized Stack functions) with depth < 0.","commonSituations":"RPC clients computing depth from arithmetic that underflowed (e.g. subtracting from 0); CLI/config parsing that produced -1 as a sentinel; copying example code with placeholder negatives.","solutions":["Pass a non-negative depth, or a large sentinel (e.g. math.MaxInt32) for 'unlimited'","Validate user/config-supplied depth values before calling the API","Clamp depth: if depth < 0 { depth = defaultDepth }"],"exampleFix":"// before\nframes, err := g.Stack(-1, false)\n// after\ndepth := requestedDepth\nif depth < 0 { depth = 50 }\nframes, err := g.Stack(depth, false)","handlingStrategy":"validation","validationCode":"func sanitizeDepth(d int) int {\n    if d < 0 {\n        return defaultMaxStackDepth // e.g. 50\n    }\n    return d\n}","typeGuard":null,"tryCatchPattern":"frames, err := g.Stack(depth, false)\nif err != nil && strings.Contains(err.Error(), \"negative maximum stack depth\") {\n    return fmt.Errorf(\"invalid depth %d: must be >= 0\", depth)\n}","preventionTips":["Validate any user/config-supplied depth before calling stack APIs","Avoid -1 sentinels; use a large positive constant for 'unlimited'","Watch for integer underflow when computing depth arithmetically"],"tags":["stacktrace","api-misuse","validation"],"backgroundTag":"invalid-argument","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}