{"record":{"id":"c1960fa98672be99","repo":"flipped-aurora/gin-vue-admin","slug":"error-c1960f","errorCode":null,"errorMessage":"读取模版文件夹失败!","messagePattern":"读取模版文件夹失败!","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_package.go","lineNumber":282,"sourceCode":"\t\tfilteredEntities := []model.SysAutoCodePackage{}\n\t\tfor i := 0; i < len(entities); i++ {\n\t\t\tif existingPackageNames[entities[i].PackageName] {\n\t\t\t\tfilteredEntities = append(filteredEntities, entities[i])\n\t\t\t}\n\t\t}\n\t\tentities = filteredEntities\n\t}\n\n\treturn entities, nil\n}\n\n// Templates 获取所有模版文件夹\n// @author: [SliverHorn](https://github.com/SliverHorn)\nfunc (s *autoCodePackage) Templates(ctx context.Context) ([]string, error) {\n\ttemplates := make([]string, 0)\n\tentries, err := os.ReadDir(\"resource\")\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"读取模版文件夹失败!\")\n\t}\n\tignoreDirs := map[string]bool{\n\t\t\"page\":     true, // page 为表单生成器\n\t\t\"function\": true, // function 为函数生成器\n\t\t\"preview\":  true, // preview 为预览代码生成器的代码\n\t\t\"mcp\":      true, // mcp 为mcp生成器的代码\n\t\t\"ai_cli\":   true, // ai_cli 为 AI CLI 生成器的代码\n\t}\n\tfor i := 0; i < len(entries); i++ {\n\t\tif entries[i].IsDir() {\n\t\t\tif ignoreDirs[entries[i].Name()] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttemplates = append(templates, entries[i].Name())\n\t\t}\n\t}\n\treturn templates, nil\n}","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_package.go#L264-L300","documentation":"AutoCodePackage.Templates lists the code-generator template folders by reading the relative directory \"resource\" with os.ReadDir. When that read fails (directory missing, not a directory, or permission denied), the underlying error is wrapped with the message \"读取模版文件夹失败!\" and returned, so the frontend template picker gets no folder list.","triggerScenarios":"Calling GET the auto-code package templates API (s.autoCodePackage.Templates) when the process working directory does not contain a \"resource\" directory — e.g. the server binary is launched from a directory other than the repo/server root, or the resource folder was deleted or not deployed.","commonSituations":"Running the compiled server binary from / or a systemd unit with a wrong WorkingDirectory; Docker image missing server/resource; renaming or moving resource/; running tests from a package directory instead of the server root.","solutions":["Start the server with its working directory set to the server root (where server/resource exists), e.g. cd server && ./gva, or fix the WorkingDirectory in the systemd/supervisor unit.","Verify the resource directory exists: ls ./resource; restore it from the repository if it was deleted.","Check directory permissions so the process user can read resource/.","If embedding/deploying differently, adjust the hard-coded \"resource\" path or run behind the documented launch script."],"exampleFix":"// before (running from wrong cwd)\n$ /opt/gva/server  # /opt/gva has no resource/\n// after\n$ cd /opt/gva/server && ./gva  # ./resource exists here","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(\"resource\"); err != nil || !info.IsDir() {\n    return fmt.Errorf(\"resource/ 模板目录不存在于工作目录 %s\", os.Getwd())\n}","typeGuard":null,"tryCatchPattern":"names, err := svc.Templates(ctx)\nif err != nil {\n    log.Printf(\"读取模板列表失败（检查工作目录下是否存在 resource/）: %v\", err)\n    return err\n}","preventionTips":["Always launch the server from the directory containing resource/ (cd server && ./gva)","Set WorkingDirectory explicitly in systemd/supervisor/Docker compose units","Add a startup health check that stats ./resource before serving","Never delete or move server/resource during deployments without checking codegen features"],"tags":["filesystem","go","codegen","working-directory"],"backgroundTag":"directory-not-found","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}