JosefNemec/Playnite · error · LocalizedException

LOC.GeneralExtensionPackageError

Error message

LOC.GeneralExtensionPackageError

What it means

Thrown as LocalizedException(LOC.GeneralExtensionPackageError) by VerifyExtensionPackage when the zip archive has no extension manifest entry (PlaynitePaths.ExtensionManifestFileName) or the parsed manifest has an empty Id. Both defects make the package unusable; the localized exception surfaces a user-facing message.

Source

Thrown at source/Playnite/Plugins/ExtensionInstaller.cs:335

        private static void QueueExtensionOperation(string extensionPath, ExtInstallType installationType)
        {
            if (currentQueue.FirstOrDefault(a => a.Path == extensionPath) == null)
            {
                currentQueue.Add(new ExtensionInstallQueueItem(extensionPath, installationType));
            }

            FileSystem.WriteStringToFile(PlaynitePaths.ExtensionQueueFilePath, Serialization.ToJson(currentQueue));
        }

        public static void VerifyExtensionPackage(string packagePath)
        {
            using (var zip = ZipFile.OpenRead(packagePath))
            {
                var manifestEntry = zip.GetEntry(PlaynitePaths.ExtensionManifestFileName);
                if (manifestEntry == null)
                {
                    logger.Error("Extension package is invalid, no manifest found.");
                    throw new LocalizedException(LOC.GeneralExtensionPackageError);
                }

                using (var logStream = manifestEntry.Open())
                {
                    using (TextReader tr = new StreamReader(logStream))
                    {
                        var manifest = Serialization.FromYaml<ExtensionManifest>(tr.ReadToEnd());
                        if (manifest.Id.IsNullOrEmpty())
                        {
                            logger.Error("Extension package is invalid, no extension ID found.");
                            throw new LocalizedException(LOC.GeneralExtensionPackageError);
                        }

                        if (!Version.TryParse(manifest.Version, out var _))
                        {
                            logger.Error($"Extension package is invalid, version is not in correct format {manifest.Version}.");
                            throw new LocalizedException(LOC.GeneralExtensionPackageError);
                        }

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Re-download the extension package in case of truncation/corruption.
  2. Rebuild the package ensuring the manifest file is at the archive root with a non-empty Id.
  3. Before installing, verify the zip contains the manifest entry and that its Id is populated.

Example fix

// before
var manifestEntry = zip.GetEntry(PlaynitePaths.ExtensionManifestFileName);
if (manifestEntry == null) { throw new LocalizedException(LOC.GeneralExtensionPackageError); }

// after
var manifestEntry = zip.GetEntry(PlaynitePaths.ExtensionManifestFileName);
if (manifestEntry == null) {
    logger.Error($"Package {packagePath} missing manifest entry '{PlaynitePaths.ExtensionManifestFileName}'.");
    throw new LocalizedException(LOC.GeneralExtensionPackageError);
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-verify the manifest entry and Id before installing.
using (var zip = ZipFile.OpenRead(packagePath)) {
    var entry = zip.GetEntry(PlaynitePaths.ExtensionManifestFileName);
    if (entry == null) { logger.Error("No manifest entry."); return; }
    using var tr = new StreamReader(entry.Open());
    var m = Serialization.FromYaml<ExtensionManifest>(tr.ReadToEnd());
    if (m.Id.IsNullOrEmpty()) { logger.Error("Manifest Id empty."); return; }
}

Type guard

static bool PackageManifestValid(string packagePath) {
    using var zip = ZipFile.OpenRead(packagePath);
    var entry = zip.GetEntry(PlaynitePaths.ExtensionManifestFileName);
    if (entry == null) return false;
    using var tr = new StreamReader(entry.Open());
    var m = Serialization.FromYaml<ExtensionManifest>(tr.ReadToEnd());
    return !m.Id.IsNullOrEmpty();
}

Try / catch

try { ExtensionInstaller.VerifyExtensionPackage(packagePath); }
catch (LocalizedException) { Dialogs.ShowMessage(resources.GetString(LOC.GeneralExtensionPackageError), LOC.Error, MessageBoxButton.OK, MessageBoxImage.Error); }

Prevention

When it happens

Trigger: VerifyExtensionPackage opens a zip that either lacks the manifest entry (zip.GetEntry returns null) or whose manifest YAML deserializes to an object with null/empty Id. Occurs during pre-install validation of an extension package.

Common situations: Corrupt or truncated download of an extension pack; package built without embedding the manifest; manifest present but Id field blank due to a packaging bug.

Related errors


AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13). Data as JSON: /api/errors/f5246d5e2a8df6fd. Report an issue: GitHub.