JosefNemec/Playnite · error · Exception

Package content invalid.

Error message

Package content invalid.

What it means

Thrown by InstallPackedFile when the package archive contains a .sln file, which indicates the package is unpackaged source rather than a Toolbox-built extension/theme pack. Playnite refuses to install raw source solutions because they are not deployable add-ons.

Source

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

            File.Delete(PlaynitePaths.ExtensionQueueFilePath);
            currentQueue = new List<ExtensionInstallQueueItem>();
            return installedExts;
        }

        public static ExtensionInstallResult InstallPackedFile<T>(string packagePath, string nanifestFileName, string rootDir, Func<string, T> newMan) where T : BaseExtensionManifest
        {
            logger.Info($"Installing extenstion/theme {packagePath}");
            var manifest = GetPackedManifest<T>(packagePath, nanifestFileName);
            if (manifest == null)
            {
                throw new FileNotFoundException("Extenstion/theme manifest not found.");
            }

            var entries = Archive.GetArchiveFiles(packagePath);
            if (entries.Any(a => a.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)))
            {
                // Check for themes that are not packaged via Toolbox.
                throw new Exception("Package content invalid.");
            }

            if (manifest is ThemeManifest themeMan)
            {
                rootDir = Path.Combine(rootDir, themeMan.Mode.ToString());
            }

            var wasUpdated = false;
            var installDir = Path.Combine(rootDir, Paths.GetSafePathName(manifest.Id));
            if (Directory.Exists(installDir))
            {
                wasUpdated = true;
                logger.Debug($"Replacing existing extenstion/theme installation: {installDir}.");
            }

            FileSystem.CreateDirectory(installDir, true);
            ZipFile.ExtractToDirectory(packagePath, installDir);
            if (Paths.AreEqual(PlaynitePaths.TempPath, Path.GetDirectoryName(packagePath)))

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Build the package with Playnite Toolbox (pack command) to produce a proper installable archive without the .sln.
  2. Exclude .sln and source files when zipping; ensure the archive contains only the built output and manifest.
  3. Verify package contents with Archive.GetArchiveFiles before attempting install.

Example fix

// before
if (entries.Any(a => a.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))) { throw new Exception("Package content invalid."); }

// after — clearer guidance
if (entries.Any(a => a.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))) {
    throw new Exception("Package contains a .sln file; it appears to be source, not a Toolbox-built pack. Build it with Toolbox first.");
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject source bundles before install.
if (Archive.GetArchiveFiles(packagePath).Any(a => a.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))) {
    logger.Error($"{packagePath} is a source bundle, not an installable pack.");
    return;
}

Type guard

static bool IsInstallablePackage(string packagePath) =>
    !Archive.GetArchiveFiles(packagePath).Any(a => a.EndsWith(".sln", StringComparison.OrdinalIgnoreCase));

Prevention

When it happens

Trigger: InstallPackedFile is given an archive whose entries include any file ending in .sln. Detected via Archive.GetArchiveFiles(packagePath).Any(... ".sln").

Common situations: Developer or user zipped the source folder (including the .sln) instead of running Toolbox packaging; a git repo export was packaged rather than a build artifact.

Related errors


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