{"record":{"id":"a3ffa119cd66e87e","repo":"JosefNemec/Playnite","slug":"extenstion-theme-manifest-not-found","errorCode":null,"errorMessage":"Extenstion/theme manifest not found.","messagePattern":"Extenstion/theme manifest not found\\.","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"source/Playnite/Plugins/ExtensionInstaller.cs","lineNumber":189,"sourceCode":"                    else\r\n                    {\r\n                        logger.Warn($\"Can't uninstall extension, directory doesn't exists anymore {queueItem}\");\r\n                    }\r\n                }\r\n            }\r\n\r\n            File.Delete(PlaynitePaths.ExtensionQueueFilePath);\r\n            currentQueue = new List<ExtensionInstallQueueItem>();\r\n            return installedExts;\r\n        }\r\n\r\n        public static ExtensionInstallResult InstallPackedFile<T>(string packagePath, string nanifestFileName, string rootDir, Func<string, T> newMan) where T : BaseExtensionManifest\r\n        {\r\n            logger.Info($\"Installing extenstion/theme {packagePath}\");\r\n            var manifest = GetPackedManifest<T>(packagePath, nanifestFileName);\r\n            if (manifest == null)\r\n            {\r\n                throw new FileNotFoundException(\"Extenstion/theme manifest not found.\");\r\n            }\r\n\r\n            var entries = Archive.GetArchiveFiles(packagePath);\r\n            if (entries.Any(a => a.EndsWith(\".sln\", StringComparison.OrdinalIgnoreCase)))\r\n            {\r\n                // Check for themes that are not packaged via Toolbox.\r\n                throw new Exception(\"Package content invalid.\");\r\n            }\r\n\r\n            if (manifest is ThemeManifest themeMan)\r\n            {\r\n                rootDir = Path.Combine(rootDir, themeMan.Mode.ToString());\r\n            }\r\n\r\n            var wasUpdated = false;\r\n            var installDir = Path.Combine(rootDir, Paths.GetSafePathName(manifest.Id));\r\n            if (Directory.Exists(installDir))\r\n            {\r","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Playnite/Plugins/ExtensionInstaller.cs#L171-L207","documentation":"Thrown as FileNotFoundException by InstallPackedFile when GetPackedManifest returns null — the extension/theme package does not contain a readable manifest at the expected path (nanifestFileName). Without a manifest the installer cannot determine the addon id, type, or install directory.","triggerScenarios":"Installing a packed extension/theme archive whose manifest file (e.g. extension.yaml) is missing, misnamed, or failed to deserialize inside the package.","commonSituations":"Package built incorrectly (manifest omitted or renamed); the package is actually a source .sln bundle rather than a Toolbox-built pack; manifest YAML is malformed so deserialization yields null.","solutions":["Rebuild the extension/theme package with Playnite Toolbox so the manifest is included at the expected path.","Inspect the archive contents to confirm the manifest filename matches nanifestFileName.","Validate the manifest YAML parses correctly before packaging."],"exampleFix":"// before\nvar manifest = GetPackedManifest<T>(packagePath, nanifestFileName);\nif (manifest == null) { throw new FileNotFoundException(\"Extenstion/theme manifest not found.\"); }\n\n// after\nvar manifest = GetPackedManifest<T>(packagePath, nanifestFileName);\nif (manifest == null) {\n    throw new FileNotFoundException($\"No valid manifest '{nanifestFileName}' found in package '{packagePath}'. Ensure it was built with Toolbox.\", packagePath);\n}","handlingStrategy":"validation","validationCode":"// Inspect the package for the manifest before installing.\nvar entries = Archive.GetArchiveFiles(packagePath);\nif (!entries.Any(e => e.EndsWith(nanifestFileName, StringComparison.OrdinalIgnoreCase))) {\n    logger.Error($\"No manifest '{nanifestFileName}' in {packagePath}\");\n    return;\n}","typeGuard":"static bool PackageHasManifest(string packagePath, string manifestFile) =>\n    Archive.GetArchiveFiles(packagePath).Any(e => e.EndsWith(manifestFile, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { ExtensionInstaller.InstallPackedFile(...); }\ncatch (FileNotFoundException ex) when (ex.Message.Contains(\"manifest not found\")) { logger.Error(ex, \"Package missing manifest.\"); }","preventionTips":["Always build packages with Toolbox so the manifest is included.","Verify archive contents before install.","Reject packages without a manifest in the addon browser."],"tags":["addon","installer","manifest","packaging"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}