{"record":{"id":"b996d9f37d59a4fe","repo":"flipped-aurora/gin-vue-admin","slug":"invalid-offsets-for-function-start-d-end-d-len","errorCode":null,"errorMessage":"invalid offsets for function: start=%d end=%d len=%d","messagePattern":"invalid offsets for function: start=(.+?) end=(.+?) len=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/ast/extract_func.go","lineNumber":56,"sourceCode":"        if line >= s && line <= e {\n            target = fd\n            startLine = s\n            endLine = e\n            return false\n        }\n        return true\n    })\n\n    if target == nil {\n        err = fmt.Errorf(\"no function encloses line %d in %s\", line, filePath)\n        return\n    }\n\n    // 使用字节偏移精确提取源码片段（包含注释与原始格式）\n    start := fset.Position(target.Pos()).Offset\n    end := fset.Position(target.End()).Offset\n    if start < 0 || end > len(src) || start >= end {\n        err = fmt.Errorf(\"invalid offsets for function: start=%d end=%d len=%d\", start, end, len(src))\n        return\n    }\n    source = string(src[start:end])\n    name = target.Name.Name\n    return\n}","sourceCodeStart":38,"sourceCodeEnd":62,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/ast/extract_func.go#L38-L62","documentation":"After locating the enclosing FuncDecl, the extractor converts its Pos/End to byte offsets and sanity-checks them against the source buffer length before slicing. This defensive error fires when the computed offsets are inconsistent with the source bytes (start<0, end>len(src), or start>=end), which should be nearly impossible for a freshly parsed file.","triggerScenarios":"Calling ExtractFuncSourceByPosition when the AST node offsets do not map into the provided src buffer — e.g. src was mutated/replaced between parse and slice, a custom/empty FileSet mismatch, or a corrupted/truncated file that still parsed with recovered errors.","commonSituations":"Parsing with parser errors recovered (ParseFile returning a partial AST plus error handled elsewhere) and then slicing offsets; concurrent modification of the file; exotic BOM/encoding issues shifting offsets.","solutions":["Re-read the file and call ExtractFuncSourceByPosition again on a fresh read/parse (do not reuse a stale src buffer)","Check that the file is not being concurrently rewritten while extracting","Ensure the file has no encoding oddities (BOM, NUL bytes) that could desync offsets","If it persists, report with the printed start/end/len values from the error message"],"exampleFix":"// before: reusing src from an earlier read while file changed on disk\nsrc, _ := os.ReadFile(path)\n// ...file rewritten by generator...\nname, out, _, _, err := ast.ExtractFuncSourceByPosition(path, line)\n// after: single call re-reads and parses atomically inside the function\nname, out, _, _, err := ast.ExtractFuncSourceByPosition(path, line)","handlingStrategy":"retry","validationCode":"if fi, err := os.Stat(filePath); err == nil && !fi.Mode().IsRegular() {\n    return fmt.Errorf(\"%s is not a regular file\", filePath)\n}","typeGuard":null,"tryCatchPattern":"name, src, _, _, err := ast.ExtractFuncSourceByPosition(filePath, line)\nif err != nil && strings.Contains(err.Error(), \"invalid offsets\") {\n    // retry once on a fresh read after a short sleep (file may have been mid-write)\n    time.Sleep(50 * time.Millisecond)\n    name, src, _, _, err = ast.ExtractFuncSourceByPosition(filePath, line)\n}","preventionTips":["Don't run extraction while generators are concurrently rewriting the target file","Keep file operations atomic (write temp file + rename) in your codegen pipeline","Treat this as a corruption signal: re-read the file before retrying"],"tags":["go","ast","offsets","codegen"],"backgroundTag":"invalid-ast-offsets","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}