{"record":{"id":"6fec0aaca349f1e6","repo":"CoplayDev/unity-mcp","slug":"output-folder-must-resolve-under-the-project-s-a","errorCode":null,"errorMessage":"'output_folder' must resolve under the project's Assets folder.","messagePattern":"'output_folder' must resolve under the project's Assets folder\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"MCPForUnity/Editor/Tools/AssetGen/ImportModelFile.cs","lineNumber":84,"sourceCode":"            }\n        }\n\n        private static string ResolveSource(string source)\n        {\n            string s = source.Replace('\\\\', '/');\n            if (s == \"Assets\" || s.StartsWith(\"Assets/\")) return AssetGenPaths.ToAbsolute(s);\n            return s; // absolute path on disk\n        }\n\n        private static string StageUnderAssets(string srcAbs, string baseName, string ext, string outputFolder)\n        {\n            string root = !string.IsNullOrWhiteSpace(outputFolder)\n                ? outputFolder\n                : AssetGenPrefs.OutputRoot + \"/Imported\";\n            if (!AssetGenPaths.TryGetAssetsFolder(root, out root))\n            {\n                if (!string.IsNullOrWhiteSpace(outputFolder))\n                    throw new ArgumentException(\"'output_folder' must resolve under the project's Assets folder.\");\n                root = AssetGenPrefs.DefaultOutputRoot + \"/Imported\";\n            }\n\n            string absRoot = AssetGenPaths.ToAbsolute(root);\n            Directory.CreateDirectory(absRoot);\n\n            string safe = SanitizeName(baseName);\n            string fileName = safe + ext;\n            string abs = Path.Combine(absRoot, fileName);\n            int n = 1;\n            while (File.Exists(abs)) { fileName = safe + \"_\" + n++ + ext; abs = Path.Combine(absRoot, fileName); }\n\n            File.Copy(srcAbs, abs);\n            return (root.TrimEnd('/') + \"/\" + fileName).Replace('\\\\', '/');\n        }\n\n        private static string SanitizeName(string raw)\n        {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/MCPForUnity/Editor/Tools/AssetGen/ImportModelFile.cs#L66-L102","documentation":"StageUnderAssets validates the user-supplied output_folder via AssetGenPaths.TryGetAssetsFolder, which requires the path to resolve under the project's Assets folder. When an explicit output_folder is given and fails this check, the import is rejected rather than writing outside Assets.","triggerScenarios":"output_folder is an absolute OS path outside the project; a relative path that escapes Assets via '..'; a path pointing at Packages/ or Library/ instead of Assets.","commonSituations":"User passes a full disk path expecting a general export; user wants to write outside the project; relative path crafted to traverse out of Assets.","solutions":["Use a path relative to Assets, e.g. 'Assets/Models/Imported' or 'Models/Imported'.","Omit output_folder to fall back to the default Assets-rooted output location.","Ensure the path does not use '..' to escape the Assets folder."],"exampleFix":"// before\n{ \"output_folder\": \"/tmp/exports\" }\n// after\n{ \"output_folder\": \"Assets/Models/Imported\" }","handlingStrategy":"validation","validationCode":"if (!string.IsNullOrWhiteSpace(outputFolder) && !AssetGenPaths.TryGetAssetsFolder(outputFolder, out _))\n{\n    throw new ArgumentException(\"'output_folder' must resolve under the project's Assets folder.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass output_folder relative to Assets (e.g. 'Assets/Models/Imported' or 'Models/Imported').","Omit output_folder to use the safe default.","Never pass an absolute OS path or a '..' traversal."],"tags":["assetgen","path","validation"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}