babalae/better-genshin-impact · error · FileNotFoundException

未找到 repo.json 文件,不是有效的脚本仓库压缩包。

Error message

未找到 repo.json 文件,不是有效的脚本仓库压缩包。

What it means

Thrown by ImportLocalRepoZipCore during zip import: after extracting the user-supplied zip to a temp dir, a recursive search for 'repo.json' found none. The zip is rejected as not a valid script repository package.

Source

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

        string targetFolderName = CenterRepoFolderName;

        try
        {
            // 阶段1: 准备 (0-10%)
            onProgress?.Invoke(0, "正在准备导入环境...");
            DirectoryHelper.DeleteReadOnlyDirectory(ReposTempPath);
            Directory.CreateDirectory(tempUnzipDir);
            onProgress?.Invoke(10, "准备完成,开始解压文件...");

            // 阶段2: 解压 (10-50%)
            await Task.Run(() => ZipFile.ExtractToDirectory(zipFilePath, tempUnzipDir, true));
            onProgress?.Invoke(50, "文件解压完成,正在验证仓库结构...");

            // 阶段3: 查找 repo.json (50-55%)
            var repoJsonPath = Directory.GetFiles(tempUnzipDir, "repo.json", SearchOption.AllDirectories).FirstOrDefault();
            if (repoJsonPath == null)
            {
                throw new FileNotFoundException("未找到 repo.json 文件,不是有效的脚本仓库压缩包。");
            }

            var repoDir = Path.GetDirectoryName(repoJsonPath)!;
            var newRepoJsonContent = await File.ReadAllTextAsync(repoJsonPath);
            onProgress?.Invoke(55, "仓库结构验证通过,正在分析仓库内容...");

            // 阶段4: 基于目录结构重合度决定目标文件夹 (55-70%)
            string? bestMatchFolder = null;
            double bestOverlap = 0;

            // 扫描已有仓库,找目录结构重合度最高的
            if (Directory.Exists(ReposPath))
            {
                foreach (var existingDir in Directory.GetDirectories(ReposPath))
                {
                    try
                    {
                        var dirName = Path.GetFileName(existingDir);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Confirm the selected zip actually contains a repo.json: open it and inspect the contents before importing.
  2. If extraction may have been partial, verify the extracted file count matches the zip's entry count before searching.
  3. Re-export/re-download the script repo zip from a trusted source.
  4. Surface the temp extraction dir path in the error so the user/dev can inspect what was actually extracted.

Example fix

// before
var repoJsonPath = Directory.GetFiles(tempUnzipDir, "repo.json", SearchOption.AllDirectories).FirstOrDefault();
if (repoJsonPath == null)
    throw new FileNotFoundException("未找到 repo.json 文件,不是有效的脚本仓库压缩包。");

// after (include what was found)
var repoJsonPath = Directory.GetFiles(tempUnzipDir, "repo.json", SearchOption.AllDirectories).FirstOrDefault();
if (repoJsonPath == null)
{
    var extracted = Directory.GetFiles(tempUnzipDir, "*", SearchOption.AllDirectories);
    throw new FileNotFoundException(
        $"未找到 repo.json 文件,不是有效的脚本仓库压缩包。解压目录 {tempUnzipDir} 共 {extracted.Length} 个文件。",
        Path.Combine(tempUnzipDir, "repo.json"));
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify the zip contains repo.json before extracting
using var archive = ZipFile.OpenRead(zipFilePath);
bool hasRepoJson = archive.Entries.Any(e => e.Name == "repo.json");
if (!hasRepoJson)
    throw new ArgumentException("所选压缩包不含 repo.json,不是脚本仓库");

Try / catch

catch (FileNotFoundException ex) when (ex.Message.Contains("repo.json"))
{
    Toast.Error("压缩包无效:缺少 repo.json,请选择正确的脚本仓库压缩包。");
}

Prevention

When it happens

Trigger: ImportLocalRepoZipCore extracts zipFilePath with ZipFile.ExtractToDirectory, then Directory.GetFiles(tempUnzipDir, "repo.json", SearchOption.AllDirectories).FirstOrDefault() returns null.

Common situations: User selected a zip that isn't a script repo (wrong file); the zip is a valid archive but the manifest was named differently or nested in a way the search should catch but didn't (e.g., the zip has a top-level folder and repo.json is inside — this should still be found by AllDirectories, so most likely the file is genuinely absent); the zip was corrupted and extraction silently dropped files.

Related errors


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