{"record":{"id":"0abd91ef2959e041","repo":"JosefNemec/Playnite","slug":"extension-already-exists-outdir","errorCode":null,"errorMessage":"Extension already exists: {outDir}","messagePattern":"Extension already exists: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/Tools/Playnite.Toolbox/Extensions.cs","lineNumber":77,"sourceCode":"            for (int i = 0; i < input.Length; i++)\r\n            {\r\n                var chr = input[i];\r\n                if (isValidInIdentifier(chr, i == 0))\r\n                {\r\n                    sb.Append(chr);\r\n                }\r\n            }\r\n\r\n            return sb.ToString();\r\n        }\r\n\r\n        public static string GenerateScriptExtension(string name, string directory)\r\n        {\r\n            var normalizedName = ConvertToValidIdentifierName(name);\r\n            var outDir = Path.Combine(directory, normalizedName);\r\n            if (Directory.Exists(outDir))\r\n            {\r\n                throw new Exception($\"Extension already exists: {outDir}\");\r\n            }\r\n\r\n            var templateArchive = Path.Combine(PlaynitePaths.ProgramPath, \"Templates\", \"Extensions\", \"PowerShellScript.zip\"); ;\r\n            ZipFile.ExtractToDirectory(templateArchive, outDir);\r\n            var pluginId = Guid.NewGuid();\r\n            foreach (var filePath in Directory.GetFiles(outDir, \"*.*\", SearchOption.AllDirectories))\r\n            {\r\n                var changed = false;\r\n                var fileContent = File.ReadAllText(filePath, Encoding.UTF8);\r\n                if (fileContent.Contains(nameReplaceMask))\r\n                {\r\n                    fileContent = fileContent.Replace(nameReplaceMask, normalizedName);\r\n                    changed = true;\r\n                }\r\n\r\n                if (fileContent.Contains(guidReplaceMask))\r\n                {\r\n                    fileContent = fileContent.Replace(guidReplaceMask, pluginId.ToString());\r","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Tools/Playnite.Toolbox/Extensions.cs#L59-L95","documentation":"Thrown by Toolbox.Extensions.GenerateScriptExtension when the target output directory (directory + normalized script name) already exists. The generator refuses to overwrite an existing extension to avoid clobbering prior work, so it hard-throws.","triggerScenarios":"Running `playnite-toolbox new` (or GenerateScriptExtension directly) with a name whose ConvertToValidIdentifierName normalization collides with an existing subdirectory under `directory` (Directory.Exists(outDir) true at line 75).","commonSituations":"Re-running the scaffolder with the same extension name in the same parent folder. A previous partial run left the directory behind. Two names that normalize to the same identifier (e.g. 'MyAddon' and 'My Addon' both -> 'MyAddon').","solutions":["Choose a different extension name whose normalized identifier does not collide.","Move or delete the existing outDir before regenerating.","Generate into a different parent `directory`.","If the existing folder is a leftover from a failed run, remove it and retry."],"exampleFix":"// before\nExtensions.GenerateScriptExtension(\"MyAddon\", @\"C:\\dev\"); // C:\\dev\\MyAddon exists -> throws\n\n// after\nExtensions.GenerateScriptExtension(\"MyAddonV2\", @\"C:\\dev\"); // new dir\n// or: Directory.Delete(@\"C:\\dev\\MyAddon\", true); first","handlingStrategy":"validation","validationCode":"var outDir = Path.Combine(directory, ConvertToValidIdentifierName(name));\nif (Directory.Exists(outDir))\n    throw new InvalidOperationException($\"Refusing to overwrite existing extension dir: {outDir}\");\n// or: pick a unique suffix","typeGuard":"static bool CanScaffoldScriptExtension(string name, string directory) => !Directory.Exists(Path.Combine(directory, ConvertToValidIdentifierName(name)));","tryCatchPattern":"try { return Extensions.GenerateScriptExtension(name, directory); }\ncatch (Exception ex) when (ex.Message.StartsWith(\"Extension already exists\")) { /* prompt user to overwrite or rename */ }","preventionTips":["Before scaffolding, check whether outDir exists and prompt to overwrite.","Keep each extension in its own unique parent folder.","Name extensions distinctly so normalizations don't collide."],"tags":["toolbox","scaffolding","filesystem","cli","playnite"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}