CoplayDev/unity-mcp · error · InvalidOperationException

File hash mismatch: {remoteEntry.Key} ({ShortHash(localBlobS

Error message

File hash mismatch: {remoteEntry.Key} ({ShortHash(localBlobSha)} != {ShortHash(remoteEntry.Value)})

What it means

ValidateFileHashes computes the git blob SHA1 of each synced local file and compares it to the remote blob SHA from the tree. A mismatch means the on-disk bytes differ from what GitHub served, indicating corruption or unwanted modification.

Source

Thrown at MCPForUnity/Editor/Setup/SkillSyncService.cs:481

            RemoveEmptyDirectories(targetRoot);
        }

        private static void ValidateFileHashes(string installRoot, Dictionary<string, string> remoteFiles, StringComparison pathComparison, Action<string> log)
        {
            var checkedCount = 0;
            foreach (var remoteEntry in remoteFiles)
            {
                var localPath = ResolvePathUnderRoot(installRoot, remoteEntry.Key, pathComparison);
                if (!File.Exists(localPath))
                {
                    throw new InvalidOperationException($"Missing synced file: {remoteEntry.Key}");
                }

                var localBlobSha = ComputeGitBlobSha1(localPath);
                if (!string.Equals(localBlobSha, remoteEntry.Value, StringComparison.Ordinal))
                {
                    throw new InvalidOperationException($"File hash mismatch: {remoteEntry.Key} ({ShortHash(localBlobSha)} != {ShortHash(remoteEntry.Value)})");
                }

                checkedCount++;
            }

            log?.Invoke($"Hash checks passed ({checkedCount}/{remoteFiles.Count}).");
        }

        internal static string ComputeGitBlobSha1(string filePath)
        {
            var bytes = File.ReadAllBytes(filePath);
            return ComputeGitBlobSha1(bytes);
        }

        internal static string ComputeGitBlobSha1(byte[] bytes)
        {
            var headerBytes = Encoding.UTF8.GetBytes($"blob {bytes.Length}\0");
            using var sha1 = SHA1.Create();

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Disable automatic line-ending/formatting on the install directory.
  2. Re-run the sync to re-download the file cleanly.
  3. Verify the file is not being rewritten by an editor or sync agent (OneDrive).
  4. For text files, confirm LF line endings are preserved end-to-end.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Line-ending conversion (CRLF vs LF) altered the bytes; a download was truncated/corrupted; an editor or formatter rewrote the file after write; a sync hook injected content.

Common situations: Unity or an IDE normalizes line endings on save; .gitattributes eol rules differ; a partial write left truncated content; encoding conversion on copy.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/19795a90f6c7b4e9. Report an issue: GitHub.