babalae/better-genshin-impact · error · Exception

路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))}

Error message

路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))}

What it means

Thrown while walking a multi-segment sourcePath through the repo tree in CheckoutPath: an intermediate path segment resolved to an entry that is NOT a Tree (it's a Blob or GitLink). You cannot descend into a file as if it were a directory, so traversal aborts.

Source

Thrown at BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs:1609

            for (int i = 0; i < pathParts.Length; i++)
            {
                entry = currentTree[pathParts[i]];
                if (entry == null)
                {
                    // 调试信息:列出当前树中的所有条目
                    // var availableEntries = string.Join(", ", currentTree.Select(e => e.Name));
                    // _logger.LogError($"在路径 '{string.Join("/", pathParts.Take(i))}' 中未找到 '{pathParts[i]}'");
                    // _logger.LogError($"可用的条目: {availableEntries}");
                    // throw new Exception($"仓库中不存在路径: {sourcePath}");
                    return;
                }

                if (i < pathParts.Length - 1)
                {
                    if (entry.TargetType != TreeEntryTargetType.Tree)
                    {
                        throw new Exception($"路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))}");
                    }
                    currentTree = (Tree)entry.Target;
                }
            }

            // 检出文件或目录
            if (entry == null)
            {
                // throw new Exception($"未找到路径: {sourcePath}");
                return;
            }

            if (entry.TargetType == TreeEntryTargetType.Blob)
            {
                // 检出单个文件
                var blob = (Blob)entry.Target;

                // 确保目标目录存在

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Validate the sourcePath against the manifest/repo layout before checkout; log the full path and the offending segment.
  2. Make the error message include the actual TargetType so devs see whether it hit a Blob or a GitLink.
  3. If case-insensitivity is the cause, normalize segment casing against the tree entries before lookup.
  4. Treat this as a manifest-authoring error and surface it to the script author with the exact conflicting segment.

Example fix

// before
if (entry.TargetType != TreeEntryTargetType.Tree)
    throw new Exception($"路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))}");

// after (include actual type)
if (entry.TargetType != TreeEntryTargetType.Tree)
    throw new InvalidOperationException(
        $"路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))} 实际类型={entry.TargetType},请检查 sourcePath={sourcePath}");
Defensive patterns

Strategy: validation

Validate before calling

// Walk the tree validating each intermediate segment is a Tree
for (int i = 0; i < pathParts.Length - 1; i++)
{
    if (currentTree[pathParts[i]] is not { TargetType: TreeEntryTargetType.Tree } t)
        throw new InvalidOperationException($"中间段不是目录: {pathParts[i]}");
    currentTree = (Tree)t.Target;
}

Type guard

static bool IsTreeSegment(Tree tree, string name) =>
    tree[name] is { TargetType: TreeEntryTargetType.Tree };

Try / catch

catch (Exception ex) when (ex.Message.Contains("不是目录"))
{
    _logger.LogError("manifest 路径冲突: {Msg}; sourcePath={Path}", ex.Message, sourcePath);
    throw;
}

Prevention

When it happens

Trigger: sourcePath like 'repo/folder/file.txt' where 'folder' is a file (Blob), not a directory. currentTree[segment] returns a Blob, then the code tries to descend (entry.Target as Tree) and rejects it because TargetType != Tree.

Common situations: A script manifest declares a path where a file occupies an intermediate segment that should be a directory (manifest typo); upstream renamed a file to a folder or vice versa; case-sensitivity mismatch where the directory exists with different casing on a case-sensitive server and the lookup resolves to a sibling file.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/0409723e9c9af1cd. Report an issue: GitHub.