{"record":{"id":"d8c1c73a65f0c96f","repo":"JosefNemec/Playnite","slug":"cannot-update-theme-that-was-not-generated-via-too","errorCode":null,"errorMessage":"Cannot update theme that was not generated via Toolbox utility.","messagePattern":"Cannot update theme that was not generated via Toolbox utility\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/Tools/Playnite.Toolbox/Themes.cs","lineNumber":280,"sourceCode":"            foreach (var subdir in dirs)\r\n            {\r\n                if (!subdir.Name.StartsWith(\"backup_\"))\r\n                {\r\n                    string targetPath = Path.Combine(destination, subdir.Name);\r\n                    BackupTheme(subdir.FullName, targetPath);\r\n                }\r\n            }\r\n        }\r\n\r\n        public static void UpdateTheme(string themeDirectory, ApplicationMode mode)\r\n        {\r\n            var themeManifestPath = Path.Combine(themeDirectory, \"theme.yaml\");\r\n            var currentThemeMan = new ThemeManifest(themeManifestPath);\r\n            var origThemeApiVersion = new Version(currentThemeMan.ThemeApiVersion);\r\n\r\n            if (!File.Exists(Path.Combine(themeDirectory, PlaynitePaths.ThemeProjFileName)))\r\n            {\r\n                throw new Exception(\"Cannot update theme that was not generated via Toolbox utility.\");\r\n            }\r\n\r\n            if (ThemeManager.GetApiVersion(mode) == origThemeApiVersion)\r\n            {\r\n                logger.Warn(\"Theme is already updated to current API version.\");\r\n                return;\r\n            }\r\n\r\n            var folder = Paths.GetNextBackupFolder(themeDirectory);\r\n            BackupTheme(themeDirectory, Paths.GetNextBackupFolder(themeDirectory));\r\n            logger.Info($\"Current theme backed up into \\\"{Path.GetFileName(folder)}\\\" folder.\");\r\n\r\n            var defaultThemeDir = Path.Combine(Paths.GetThemesPath(mode), \"Default\");\r\n            var origFilesZip = Path.Combine(Paths.ChangeLogsDir, currentThemeMan.ThemeApiVersion + \".zip\");\r\n            var themeChanges = Themes.GetThemeChangelog(origThemeApiVersion, mode);\r\n            if (!themeChanges.HasItems())\r\n            {\r\n                logger.Info(\"No files to update.\");\r","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Tools/Playnite.Toolbox/Themes.cs#L262-L298","documentation":"Thrown by Themes.UpdateTheme when the target theme directory lacks Theme.csproj (PlaynitePaths.ThemeProjFileName). Toolbox only knows how to update themes it generated (which ship a Theme.csproj); a hand-made theme without that project file cannot be diffed/patched against changelog zips, so the operation aborts before computing versions or backing up.","triggerScenarios":"Calling UpdateTheme on a theme folder that was authored manually or imported from elsewhere and never had a Theme.csproj. The method first loads theme.yaml, then checks for Theme.csproj and throws if absent.","commonSituations":"Updating a downloaded/custom theme that was not created via `Toolbox new <ThemeType>`; theme folder where Theme.csproj was deleted or excluded; treating a .pthm-extracted theme as Toolbox-generated.","solutions":["Only call UpdateTheme on themes created by Toolbox (`Toolbox new DesktopTheme`/`FullscreenTheme`), which produce Theme.csproj.","If you have a hand-made theme, regenerate it via `new`, port your XAML overrides in, then use UpdateTheme.","Restore Theme.csproj into the theme directory if it was accidentally removed (regenerate via `new` and copy the project file).","Verify with File.Exists(Path.Combine(themeDirectory, \"Theme.csproj\")) before calling UpdateTheme."],"exampleFix":"// before\nThemes.UpdateTheme(themeDir, mode); // no Theme.csproj present\n\n// after\nif (!File.Exists(Path.Combine(themeDir, PlaynitePaths.ThemeProjFileName)))\n    throw new InvalidOperationException(\"Theme not Toolbox-generated; cannot update.\");\nThemes.UpdateTheme(themeDir, mode);","handlingStrategy":"validation","validationCode":"if (!File.Exists(Path.Combine(themeDirectory, PlaynitePaths.ThemeProjFileName)))\n    throw new InvalidOperationException($\"{themeDirectory} is not a Toolbox-generated theme (no Theme.csproj).\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only run UpdateTheme against themes created by `Toolbox new <ThemeType>`.","Port hand-made themes into a fresh Toolbox scaffold before attempting an API update.","Confirm Theme.csproj presence before calling UpdateTheme."],"tags":["themes","toolbox","update","precondition","filesystem"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}