{"record":{"id":"d6b7f209f1c13439","repo":"MaterialDesignInXAML/MaterialDesignInXamlToolkit","slug":"did-not-find-repository-root","errorCode":null,"errorMessage":"Did not find repository root","messagePattern":"Did not find repository root","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MaterialDesignToolkit.ResourceGeneration/PathHelper.cs","lineNumber":20,"sourceCode":"\npublic static class PathHelper\n{\n    private static readonly Lazy<string> _repoRoot = new(FindRepoRoot);\n    public static string RepositoryRoot => _repoRoot.Value;\n\n\n    private static string FindRepoRoot()\n    {\n        for (string? currentDirectory = Path.GetFullPath(\".\");\n            !string.IsNullOrEmpty(Path.GetDirectoryName(currentDirectory));\n            currentDirectory = Path.GetDirectoryName(currentDirectory))\n        {\n            if (Directory.Exists(Path.Combine(currentDirectory!, \".git\")))\n            {\n                return currentDirectory!;\n            }\n        }\n        throw new InvalidOperationException(\"Did not find repository root\");\n    }\n}\n","sourceCodeStart":2,"sourceCodeEnd":23,"githubUrl":"https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/98edec3a0b96ef272c587b14bcd67ef5f928a7ed/src/MaterialDesignToolkit.ResourceGeneration/PathHelper.cs#L2-L23","documentation":"PathHelper.FindRepoRoot walks upward from the current working directory looking for a directory literally named '.git'; if the loop reaches the filesystem root without finding one it throws InvalidOperationException. This is an environment probe used by the MaterialDesign resource-generation codegen tool to anchor its hard-coded relative output paths (e.g. ..\\..\\..\\..\\MaterialDesignColors.Wpf\\Themes). It throws purely because the process was started from outside any git checkout, so the tool cannot know where to write generated files.","triggerScenarios":"Running the ResourceGeneration console app with a working directory that is not inside the repository tree, running it from a source tarball/zip export that omits the .git folder, or running it under CI that does a shallow/git-archive checkout without a .git directory. The check is Directory.Exists(<dir>/.git), so a worktree whose .git is a file (git worktree) instead of a directory will also fail this test.","commonSituations":"Running dotnet run on the generator from the wrong folder; copying the source tree without the .git metadata; building in a sandbox/container where the source was rsync'd without hidden dirs; using 'git archive' or downloading the GitHub ZIP (neither includes .git); switching to a git worktree where .git is a pointer file rather than a folder.","solutions":["Run the generator with its working directory set to a folder inside the cloned repository (e.g. the src/MaterialDesignToolkit.ResourceGeneration project folder), not from /tmp, ~, or the bin/ output directory.","Confirm a real .git directory exists in an ancestor of the working directory with 'git rev-parse --git-dir'; if that prints a path, .git is present.","If you intentionally lack .git (archive build), make FindRepoRoot accept an override such as the MATERIALDESIGN_REPO_ROOT env var, or a '.repo-root' marker file, before falling back to the throw.","If you are in a git worktree (where .git is a file), change the probe to also accept a .git file, or use LibGit2Sharp/Native git to resolve the root instead of Directory.Exists.","Wrap the access to PathHelper.RepositoryRoot so the InvalidOperationException is caught and rethrown with the offending start path for faster diagnosis."],"exampleFix":"// before\nprivate static string FindRepoRoot()\n{\n    for (string? currentDirectory = Path.GetFullPath(\".\");\n        !string.IsNullOrEmpty(Path.GetDirectoryName(currentDirectory));\n        currentDirectory = Path.GetDirectoryName(currentDirectory))\n    {\n        if (Directory.Exists(Path.Combine(currentDirectory!, \".git\")))\n            return currentDirectory!;\n    }\n    throw new InvalidOperationException(\"Did not find repository root\");\n}\n\n// after\nprivate static string FindRepoRoot()\n{\n    var fromEnv = Environment.GetEnvironmentVariable(\"MATERIALDESIGN_REPO_ROOT\");\n    if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv))\n        return Path.GetFullPath(fromEnv);\n\n    for (string? currentDirectory = Path.GetFullPath(\".\");\n        !string.IsNullOrEmpty(Path.GetDirectoryName(currentDirectory));\n        currentDirectory = Path.GetDirectoryName(currentDirectory))\n    {\n        var git = Path.Combine(currentDirectory!, \".git\");\n        // accept directory, git-worktree pointer file, or a marker file for archive builds\n        if (Directory.Exists(git) || File.Exists(git) ||\n            File.Exists(Path.Combine(currentDirectory!, \".repo-root\")))\n            return currentDirectory!;\n    }\n    throw new InvalidOperationException(\n        $\"Did not find repository root starting from '{Path.GetFullPath(\".\")}'. \" +\n        \"Run from inside the repo checkout or set MATERIALDESIGN_REPO_ROOT.\");\n}","handlingStrategy":"validation","validationCode":"string cwd = Path.GetFullPath(\".\");\nbool foundGit = false;\nfor (string? d = cwd; !string.IsNullOrEmpty(Path.GetDirectoryName(d)); d = Path.GetDirectoryName(d))\n{\n    if (Directory.Exists(Path.Combine(d!, \".git\")) || File.Exists(Path.Combine(d!, \".git\")))\n    {\n        foundGit = true;\n        break;\n    }\n}\nif (!foundGit)\n    throw new InvalidOperationException(\n        $\"Not running inside a git checkout (cwd={cwd}). cd into the repo or set MATERIALDESIGN_REPO_ROOT.\");","typeGuard":"// predicate a caller can check before touching PathHelper.RepositoryRoot\nstatic bool IsInsideRepo(string path) =>\n    EnumerateAncestors(Path.GetFullPath(path)).Any(d =>\n        Directory.Exists(Path.Combine(d, \".git\")) || File.Exists(Path.Combine(d, \".git\")));\n\nstatic IEnumerable<string> EnumerateAncestors(string dir)\n{\n    for (string? d = dir; !string.IsNullOrEmpty(Path.GetDirectoryName(d)); d = Path.GetDirectoryName(d))\n        yield return d!;\n}","tryCatchPattern":"try\n{\n    var root = PathHelper.RepositoryRoot;\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"repository root\"))\n{\n    // report cwd + hint rather than letting the generic throw propagate\n    throw new InvalidOperationException(\n        $\"{ex.Message} (search started from '{Path.GetFullPath(\".\")}')\", ex);\n}","preventionTips":["Always run dotnet run on the ResourceGeneration project from within the cloned repository tree, never from /tmp, ~, or the bin folder.","Document the required working directory in the project README so CI/run scripts set it explicitly.","Add a launchSettings.json with a workingDirectory pointing at the project folder so IDE runs anchor correctly.","For archive/ZIP builds that lack .git, ship a .repo-root marker file or accept a MATERIALDESIGN_REPO_ROOT env override."],"tags":["csharp","codegen","filesystem","repository","environment"],"backgroundTag":null,"analyzedSha":"98edec3a0b96ef272c587b14bcd67ef5f928a7ed","analyzedAt":"2026-08-13T14:31:19.111Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}