{"record":{"id":"d8dbd2af335c6549","repo":"JosefNemec/Playnite","slug":"manifest-file-playnitepaths-thememanifestfilenam","errorCode":null,"errorMessage":"Manifest file ({PlaynitePaths.ThemeManifestFileName}) not found!","messagePattern":"Manifest file \\((.+?)\\) not found!","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/Tools/Playnite.Toolbox/Themes.cs","lineNumber":177,"sourceCode":"            }\r\n\r\n            if (file1Info.Extension.Equals(\".xaml\", StringComparison.OrdinalIgnoreCase))\r\n            {\r\n                return Xml.AreEqual(File.ReadAllText(file1), File.ReadAllText(file2));\r\n            }\r\n            else\r\n            {\r\n                return FileSystem.GetMD5(file1) == FileSystem.GetMD5(file2);\r\n            }\r\n        }\r\n\r\n        public static string PackageTheme(string themeDirectory, string targetPath, ApplicationMode mode)\r\n        {\r\n            var dirInfo = new DirectoryInfo(themeDirectory);\r\n            var manifestPath = Path.Combine(themeDirectory, PlaynitePaths.ThemeManifestFileName);\r\n            if (!File.Exists(manifestPath))\r\n            {\r\n                throw new Exception($\"Manifest file ({PlaynitePaths.ThemeManifestFileName}) not found!\");\r\n            }\r\n\r\n            var extInfo = ExtensionInstaller.GetThemeManifest(manifestPath);\r\n            if (extInfo.Id.IsNullOrEmpty())\r\n            {\r\n                throw new Exception(\"Cannot package theme, ID is missing!\");\r\n            }\r\n\r\n            extInfo.VerifyManifest();\r\n\r\n            var apiVer = extInfo.Mode == ApplicationMode.Desktop ? ThemeManager.DesktopApiVersion : ThemeManager.FullscreenApiVersion;\r\n            var themeApiVer = Version.Parse(extInfo.ThemeApiVersion);\r\n            if (themeApiVer > apiVer)\r\n            {\r\n                throw new Exception($\"Cannot package theme. Unsupported API version detected: {themeApiVer}\");\r\n            }\r\n            else if (themeApiVer != apiVer)\r\n            {\r","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Tools/Playnite.Toolbox/Themes.cs#L159-L195","documentation":"Thrown by Themes.PackageTheme when themeDirectory has no theme.yaml (PlaynitePaths.ThemeManifestFileName). The method resolves manifestPath = Path.Combine(themeDirectory, \"theme.yaml\") and aborts before reading anything. Symmetrical to the extension manifest check; the theme packer needs the manifest for Id, Version, Mode, and ThemeApiVersion.","triggerScenarios":"Calling PackageTheme(themeDirectory, targetPath, mode) where themeDirectory lacks theme.yaml — e.g., pointing at a theme's source/Bin folder, or at the parent Themes directory instead of the individual theme folder.","commonSituations":"Theme authored by hand without theme.yaml; manifest renamed to theme.yml or theme.yaml.txt; CWD-relative themeDirectory resolving to the wrong place; updating from an older layout where the manifest had a different name.","solutions":["Confirm theme.yaml exists directly inside themeDirectory (exact name, .yaml not .yml).","Regenerate via `Toolbox new DesktopTheme`/`FullscreenTheme` to produce a valid theme.yaml scaffold.","Point PackageTheme at the directory that contains theme.yaml, not a parent or sibling.","Resolve themeDirectory to an absolute path before calling."],"exampleFix":"// before\nThemes.PackageTheme(@\".\\MyTheme\\bin\", out, mode);\n\n// after\nvar themeDir = Path.GetFullPath(@\".\\MyTheme\");\nif (!File.Exists(Path.Combine(themeDir, PlaynitePaths.ThemeManifestFileName)))\n    throw new FileNotFoundException(\"theme.yaml missing\", themeDir);\nThemes.PackageTheme(themeDir, out, mode);","handlingStrategy":"validation","validationCode":"var manifestPath = Path.Combine(themeDirectory, PlaynitePaths.ThemeManifestFileName);\nif (!File.Exists(manifestPath))\n    throw new FileNotFoundException($\"theme.yaml not found at {manifestPath}\", manifestPath);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Name the manifest exactly theme.yaml (not .yml) and place it inside the theme directory.","Assert File.Exists(theme.yaml) before calling PackageTheme.","Resolve themeDirectory to an absolute path so a wrong CWD cannot cause a false miss."],"tags":["themes","packaging","manifest","toolbox","filesystem","precondition"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}