{"record":{"id":"d95a85bc0b965d75","repo":"JosefNemec/Playnite","slug":"no-addon-manifest-installer-url","errorCode":null,"errorMessage":"No addon manifest installer url.","messagePattern":"No addon manifest installer url\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/Playnite/Manifests/AddonManifests.cs","lineNumber":228,"sourceCode":"        }\r\n\r\n        public override string ToString()\r\n        {\r\n            return Name;\r\n        }\r\n\r\n        public void DownloadInstallerManifest()\r\n        {\r\n            DownloadInstallerManifest(new CancellationToken());\r\n        }\r\n\r\n        public void DownloadInstallerManifest(CancellationToken cancelToken)\r\n        {\r\n            try\r\n            {\r\n                if (InstallerManifestUrl.IsNullOrEmpty())\r\n                {\r\n                    throw new Exception(\"No addon manifest installer url.\");\r\n                }\r\n\r\n                if (InstallerManifestUrl.StartsWith(\"http\", StringComparison.OrdinalIgnoreCase))\r\n                {\r\n                    installerManifest = PlayniteApplication.Current.ServicesClient.GetAddonInstaller(AddonId);\r\n                }\r\n                else if (File.Exists(InstallerManifestUrl))\r\n                {\r\n                    installerManifest = Serialization.FromYamlFile<AddonInstallerManifest>(InstallerManifestUrl);\r\n                }\r\n                else\r\n                {\r\n                    throw new Exception($\"Uknown installer manifest url format {InstallerManifestUrl}.\");\r\n                }\r\n            }\r\n            catch (Exception exc) when (!PlayniteEnvironment.ThrowAllErrors)\r\n            {\r\n                logger.Error(exc, \"Failed to get addon installer manifest data.\");\r","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Playnite/Manifests/AddonManifests.cs#L210-L246","documentation":"Thrown by AddonManifest.DownloadInstallerManifest when InstallerManifestUrl is null or empty. The method cannot fetch the installer manifest without a source URL; the check precedes the http/file dispatch and is a hard precondition for addon installation.","triggerScenarios":"Calling DownloadInstallerManifest on an AddonManifest whose InstallerManifestUrl was never set — e.g. a manifest parsed from a source that omitted the field, or an addon record built in memory without the url.","commonSituations":"Addon repository returned a manifest missing the installer URL; a localized/older manifest schema omitted the field; manual addon registration skipped the URL.","solutions":["Validate InstallerManifestUrl is non-empty before requesting the installer manifest.","Re-fetch the addon listing from the repository to populate a valid InstallerManifestUrl.","If installing from a local file, ensure the manifest's InstallerManifestUrl points at a real path or http URL."],"exampleFix":"// before\nif (InstallerManifestUrl.IsNullOrEmpty()) { throw new Exception(\"No addon manifest installer url.\"); }\n\n// after\nif (InstallerManifestUrl.IsNullOrEmpty()) {\n    logger.Warn($\"Addon {AddonId} has no installer manifest URL; cannot download.\");\n    installerManifest = new AddonInstallerManifest();\n    return;\n}","handlingStrategy":"validation","validationCode":"// Confirm the installer URL is set before downloading.\nif (manifest.InstallerManifestUrl.IsNullOrEmpty()) {\n    logger.Warn($\"Addon {manifest.AddonId} has no installer URL.\");\n    return;\n}","typeGuard":"static bool HasInstallerUrl(AddonManifest m) => !m.InstallerManifestUrl.IsNullOrEmpty();","tryCatchPattern":null,"preventionTips":["Validate addon manifests from the repository include InstallerManifestUrl.","Show a clear error in the addon browser when the URL is missing.","Refresh the addon listing if manifests are incomplete."],"tags":["addon","manifest","validation","network"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}