{"record":{"id":"529b2206598425da","repo":"flipped-aurora/gin-vue-admin","slug":"d-529b22","errorCode":null,"errorMessage":"自动代码回滚索引无效: %d","messagePattern":"自动代码回滚索引无效: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_task.go","lineNumber":219,"sourceCode":"\t}\n\tif exists != file.Existed || (file.Existed && currentHash != file.BeforeHash) {\n\t\treturn false, fmt.Errorf(\"%w: %s\", errAutoCodeFileConflict, file.TargetPath)\n\t}\n\tif err = os.MkdirAll(filepath.Dir(file.TargetPath), 0o755); err != nil {\n\t\treturn false, fmt.Errorf(\"创建目标目录 %s 失败: %w\", filepath.Dir(file.TargetPath), err)\n\t}\n\tif err = os.Rename(file.StagedPath, file.TargetPath); err != nil {\n\t\treturn false, fmt.Errorf(\"原子发布 %s 失败: %w\", file.TargetPath, err)\n\t}\n\tfile.StagedPath = \"\"\n\treturn true, nil\n}\n\nfunc (task *autoCodeFileTask) rollback(applied []int) error {\n\tfor i := len(applied) - 1; i >= 0; i-- {\n\t\tindex := applied[i]\n\t\tif index < 0 || index >= len(task.files) {\n\t\t\treturn fmt.Errorf(\"自动代码回滚索引无效: %d\", index)\n\t\t}\n\t\tfile := &task.files[index]\n\t\tcurrentHash, exists, err := hashAutoCodeTarget(file.TargetPath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif file.Existed && exists && currentHash == file.BeforeHash {\n\t\t\tcontinue\n\t\t}\n\t\tif !exists || currentHash != file.AfterHash {\n\t\t\treturn fmt.Errorf(\"%w: %s\", errAutoCodeFileConflict, file.TargetPath)\n\t\t}\n\t\tif !file.Existed {\n\t\t\tif err = os.Remove(file.TargetPath); err != nil && !errors.Is(err, fs.ErrNotExist) {\n\t\t\t\treturn fmt.Errorf(\"删除新建文件 %s 失败: %w\", file.TargetPath, err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_task.go#L201-L237","documentation":"During rollback of an auto-code file transaction, each applied file index is validated against the task's file list. If an index in `applied` is negative or beyond the number of tracked files, rollback aborts with this error instead of touching the filesystem. This is an internal invariant guard — it should never fire through normal API use, only when the applied-index bookkeeping is corrupted or rollback is called with a slice built against a different task.","triggerScenarios":"Calling autoCodeFileTask.rollback(applied) with an `applied` slice that contains an out-of-range index: either produced by a buggy `apply`/publisher implementation, a task whose `files` slice was mutated after apply, or reusing indexes from another task instance.","commonSituations":"Custom modifications to the auto-code commit pipeline, concurrent mutation of task.files, or tests calling rollback directly with hand-built index slices.","solutions":["Audit any custom autoCodeFilePublisher / apply logic so it only appends indexes returned by `for index := range task.files` of the same task instance","Ensure nothing mutates task.files between apply and rollback (rollback runs inside commitAutoCodeFileTask synchronously; do not share the task across goroutines)","If hit in stock gin-vue-admin code, report it — the invariant is broken upstream, and the joined error will show the original cause plus 回滚自动代码文件失败"],"exampleFix":"// before (hypothetical custom publisher returning a stale index)\napplied = append(applied, staleIndex)\n// after\nfor index := range task.files {\n    if task.files[index].Kind == kind {\n        applied = append(applied, index)\n    }\n}","handlingStrategy":"validation","validationCode":"func validateApplied(applied []int, files int) error {\n    for _, i := range applied {\n        if i < 0 || i >= files {\n            return fmt.Errorf(\"applied index %d out of range [0,%d)\", i, files)\n        }\n    }\n    return nil\n}","typeGuard":"func validIndex(i, n int) bool { return i >= 0 && i < n }","tryCatchPattern":"err := task.rollback(applied)\nif err != nil {\n    // joined error includes 回滚自动代码文件失败\n    if errors.Is(err, errAutoCodeFileConflict) { /* reconcile files */ }\n    log.Printf(\"rollback failed: %v\", err)\n}","preventionTips":["Never construct applied-index slices outside apply()","Never mutate task.files after prepareAutoCodeFileTask returns","Do not share an autoCodeFileTask across goroutines","Only call rollback through commitAutoCodeFileTask"],"tags":["go","code-generation","rollback","internal-invariant"],"backgroundTag":"rollback-index-out-of-range","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}