{"record":{"id":"67cd7dd57105ac4f","repo":"babalae/better-genshin-impact","slug":"repo","errorCode":null,"errorMessage":"仓库结构错误：未找到 repo/ 子目录","messagePattern":"仓库结构错误：未找到 repo/ 子目录","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs","lineNumber":1373,"sourceCode":"        return Repository.IsValid(repoPath) && !Directory.Exists(Path.Combine(repoPath, \"repo\"));\n    }\n\n    /// <summary>\n    /// 获取仓库中 repo/ 子目录的树对象\n    /// </summary>\n    private Tree GetRepoSubdirectoryTree(Repository repo)\n    {\n        var commit = repo.Head?.Tip;\n        if (commit == null)\n        {\n            throw new Exception(\"仓库HEAD未指向任何提交\");\n        }\n\n        // 脚本内容都在 repo/ 子目录下\n        var repoEntry = commit.Tree[\"repo\"];\n        if (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)\n        {\n            throw new Exception(\"仓库结构错误：未找到 repo/ 子目录\");\n        }\n\n        return (Tree)repoEntry.Target;\n    }\n\n    /// <summary>\n    /// 从中央仓库读取文件内容\n    /// </summary>\n    /// <param name=\"relPath\">相对于仓库根目录的路径</param>\n    /// <returns>文件内容，如果文件不存在则返回null</returns>\n    public string? ReadFileFromCenterRepo(string relPath)\n    {\n        try\n        {\n            var repoPath = CenterRepoPath;\n\n            // 判断是否为 Git 仓库\n            bool isGitRepo = IsGitRepository(repoPath);","sourceCodeStart":1355,"sourceCodeEnd":1391,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs#L1355-L1391","documentation":"Thrown by GetRepoSubdirectoryTree when HEAD's tip commit exists but its root tree has no entry named 'repo', or the entry exists but is not a Tree (e.g., it's a file/symlink). The script repo contract requires all script content to live under a top-level 'repo/' directory.","triggerScenarios":"commit.Tree[\"repo\"] returns null or returns a TreeEntry whose TargetType != TreeEntryTargetType.Tree. Happens when the cloned repository doesn't follow the expected layout, the 'repo' entry is a file rather than a directory, or the wrong commit/branch was checked out.","commonSituations":"User configured a non-conforming repository as the script source; upstream restructured and moved scripts out of 'repo/'; a shallow clone with Depth=1 fetched a historical commit before 'repo/' existed; wrong branch checked out (e.g., 'main' has no repo/ but 'release' does).","solutions":["Verify the repository layout: `git ls-tree HEAD <repoUrl>` — confirm a 'repo' directory exists at the root.","Ensure the correct branch is checked out before calling GetRepoSubdirectoryTree (the repo may have repo/ only on 'release').","If the upstream layout changed, update the hardcoded 'repo' entry name in GetRepoSubdirectoryTree to the new convention, or search recursively for the manifest.","Provide a clearer error listing available top-level entries so users/devs can see what the repo actually contains."],"exampleFix":"// before\nvar repoEntry = commit.Tree[\"repo\"];\nif (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)\n    throw new Exception(\"仓库结构错误：未找到 repo/ 子目录\");\n\n// after (diagnostic)\nvar repoEntry = commit.Tree[\"repo\"];\nif (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)\n{\n    var available = string.Join(\", \", commit.Tree.Select(e => $\"{e.Name}({e.TargetType})\"));\n    throw new InvalidOperationException(\n        $\"仓库结构错误：未找到 repo/ 子目录。当前顶层条目: {available}\");\n}","handlingStrategy":"validation","validationCode":"var repoEntry = commit.Tree[\"repo\"];\nif (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)\n{\n    var avail = string.Join(\", \", commit.Tree.Select(e => e.Name));\n    throw new InvalidOperationException(\n        $\"未找到 repo/ 子目录。顶层条目: {avail}\");\n}","typeGuard":"static bool HasRepoSubdir(Repository repo) =>\n    repo.Head?.Tip?.Tree[\"repo\"] is { TargetType: TreeEntryTargetType.Tree };","tryCatchPattern":"catch (Exception ex) when (ex.Message.Contains(\"repo/\"))\n{\n    _logger.LogError(\"仓库结构不符合预期，请确认仓库约定：{Msg}\", ex.Message);\n    Toast.Error($\"仓库结构错误，缺少 repo/ 目录。请重新下载或更换仓库。\");\n}","preventionTips":["Document the required 'repo/' layout in the script repo README.","Validate repo layout right after clone, before any checkout.","Make the expected subdirectory configurable if upstream may change it."],"tags":["git","libgit2sharp","repo-structure","layout","precondition"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}