CoplayDev/unity-mcp · error · ArgumentException

zipPath required

Error message

zipPath required

What it means

SafeZipExtractor.ExtractTo requires a non-empty zipPath and destDir; an empty zipPath throws ArgumentException with paramName zipPath. This is an entry-point argument guard before opening any file stream.

Source

Thrown at MCPForUnity/Editor/Services/AssetGen/Import/SafeZipExtractor.cs:23

namespace MCPForUnity.Editor.Services.AssetGen.Import
{
    /// <summary>
    /// Extracts a .zip into a destination directory while rejecting Zip-Slip path traversal:
    /// every entry's resolved target must stay inside <c>destDir</c>. Directory entries are
    /// created; file entries are written by copying the entry stream (no reliance on the
    /// ZipFileExtensions helper). Used to unpack marketplace model archives (e.g. Sketchfab).
    ///
    /// When <paramref name="allowedExtensions"/> is supplied, file entries whose extension is not
    /// on the allowlist are SKIPPED (not written). Callers that extract UNTRUSTED archives into the
    /// Assets tree MUST pass an allowlist of inert asset types so executable content (.cs/.dll/
    /// .asmdef) can never land under Assets/ and be compiled/loaded by the Editor.
    /// </summary>
    public static class SafeZipExtractor
    {
        public static void ExtractTo(string zipPath, string destDir, ISet<string> allowedExtensions = null)
        {
            if (string.IsNullOrEmpty(zipPath)) throw new ArgumentException("zipPath required", nameof(zipPath));
            if (string.IsNullOrEmpty(destDir)) throw new ArgumentException("destDir required", nameof(destDir));

            Directory.CreateDirectory(destDir);
            string destFull = Path.GetFullPath(destDir);
            string prefix = destFull.EndsWith(Path.DirectorySeparatorChar.ToString())
                ? destFull
                : destFull + Path.DirectorySeparatorChar;

            using (FileStream fs = File.OpenRead(zipPath))
            using (var archive = new ZipArchive(fs, ZipArchiveMode.Read))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    string name = entry.FullName;
                    if (string.IsNullOrEmpty(name)) continue;

                    // Reject traversal / absolute paths up front.
                    if (name.Contains("..") || Path.IsPathRooted(name))

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Ensure the zip download completed and produced a real file path before extracting.
  2. Guard for null/empty zipPath at the call site and surface the upstream failure.

Example fix

// before
SafeZipExtractor.ExtractTo(downloadedPath, destDir); // downloadedPath may be ""

// after
if (string.IsNullOrEmpty(downloadedPath) || !File.Exists(downloadedPath))
    throw new InvalidOperationException("Download produced no archive to extract.");
SafeZipExtractor.ExtractTo(downloadedPath, destDir);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(zipPath) || !File.Exists(zipPath))
    throw new InvalidOperationException("No archive file found to extract; check the download step.");
SafeZipExtractor.ExtractTo(zipPath, destDir, allowedExtensions);

Type guard

static bool IsValidArchivePath(string p) => !string.IsNullOrWhiteSpace(p) && File.Exists(p);

Try / catch

try { SafeZipExtractor.ExtractTo(zipPath, destDir, allowed); }
catch (ArgumentException ex) when (ex.Message.Contains("zipPath required"))
{
    // The download produced no archive; re-run download before retrying extraction.
    throw new InvalidOperationException("Download step produced no archive.", ex);
}

Prevention

When it happens

Trigger: Calling ExtractTo with a null or empty zipPath; a download step that produced no file and forwarded an empty path.

Common situations: An upstream marketplace download failed silently leaving no local archive; path resolution returned empty due to a missing config; a caller forgetting to pass the downloaded archive path.

Related errors


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