CoplayDev/unity-mcp · error · Exception

provider returned a disallowed file type '.

Error message

provider returned a disallowed file type '.{ext}'

What it means

WriteFile checks the provider-returned file extension against a per-kind allowlist (image/model/marketplace), defaulting to NoAllowedExtensions (fail-closed) for any unknown kind. A disallowed extension throws a generic Exception. This is a security gate preventing unexpected or executable content from landing under Assets/.

Solutions

  1. Confirm the provider legitimately returns that type and, if safe, add it to the relevant AllowedExtensions list for the kind.
  2. Verify OverrideExt/Ext on the Runner is set to an allowed extension for the job kind.
  3. For any new job kind, register an explicit allowlist rather than relying on the fail-closed default in production.
Defensive patterns

Strategy: validation

Validate before calling

// Before writing, confirm the resolved extension is allowlisted for the job kind.
string ext = (r.OverrideExt ?? r.Ext ?? "bin").TrimStart('.').ToLowerInvariant();
if (!AssetGenJob.IsAllowedResultExtension(r.Job.Kind, ext))
    throw new InvalidOperationException($"Provider ext '.{ext}' is not allowed for kind '{r.Job.Kind}'.");

Try / catch

try { AssetGenJob.WriteFile(runner, bytes); }
catch (Exception ex) when (ex.Message.Contains("disallowed file type"))
{
    // Either the provider misbehaved or the allowlist needs updating for a safe new format.
    Log.Warn(ex.Message);
    throw;
}

Prevention

When it happens

Trigger: A provider returns a file type not in the kind's allowlist (e.g. a model job returning .exe or .zip when only model formats are allowed); an unknown job kind with no allowlist entry; OverrideExt or Ext on the Runner mis-set to a disallowed value.

Common situations: A provider API change returning a new format not yet allowlisted; a misconfigured ext override in tests; a new job kind registered without an allowlist entry, hitting the fail-closed default.

Related errors


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

Appendix: source

Thrown at MCPForUnity/Editor/Services/AssetGen/AssetGenJobManager.cs:484

        private static HashSet<string> AllowedExtensionsFor(string kind)
        {
            switch ((kind ?? string.Empty).ToLowerInvariant())
            {
                case "audio": return AudioAllowedExtensions;
                case "image": return ImageAllowedExtensions;
                case "model":
                case "marketplace": return ModelAllowedExtensions;
                default: return NoAllowedExtensions; // fail closed for unexpected kinds
            }
        }

        private static string WriteFile(Runner r, byte[] bytes)
        {
            string chosen = !string.IsNullOrEmpty(r.OverrideExt) ? r.OverrideExt : r.Ext;
            string ext = string.IsNullOrEmpty(chosen) ? "bin" : chosen.TrimStart('.').ToLowerInvariant();
            if (!IsAllowedResultExtension(r.Job.Kind, ext))
                throw new Exception($"provider returned a disallowed file type '.{ext}'");
            string requestedRoot = !string.IsNullOrEmpty(r.OutputFolder) ? r.OutputFolder
                                                                         : (AssetGenPrefs.OutputRoot + "/" + r.Subfolder);
            if (!AssetGenPaths.TryGetAssetsFolder(requestedRoot, out string root))
                root = AssetGenPrefs.DefaultOutputRoot + "/" + r.Subfolder;
            string absRoot = AssetGenPaths.ToAbsolute(root);
            Directory.CreateDirectory(absRoot);
            string baseName = SanitizeName(r.Name);
            string fileName = baseName + "." + ext;
            string abs = Path.Combine(absRoot, fileName);
            int n = 1;
            while (File.Exists(abs)) { fileName = baseName + "_" + n++ + "." + ext; abs = Path.Combine(absRoot, fileName); }
            File.WriteAllBytes(abs, bytes);
            return (root.TrimEnd('/') + "/" + fileName).Replace('\\', '/');
        }

        private static string NameFrom(string explicitName, string prompt, string jobId)
        {
            if (!string.IsNullOrWhiteSpace(explicitName)) return explicitName;

View on GitHub (pinned to c21bf496bc)