JosefNemec/Playnite · error · Exception

Manifest file ({PlaynitePaths.ExtensionManifestFileName}) no

Error message

Manifest file ({PlaynitePaths.ExtensionManifestFileName}) not found!

What it means

Thrown by Extensions.PackageExtension when the supplied extension directory does not contain extension.yaml (PlaynitePaths.ExtensionManifestFileName). The method resolves manifestPath = Path.Combine(extDirectory, "extension.yaml") and aborts before reading, zipping, or version-checking anything. It is a precondition check: the packer cannot proceed without the manifest that declares the extension's Id and Version.

Source

Thrown at source/Tools/Playnite.Toolbox/Extensions.cs:189

                case ExtensionType.MetadataProvider:
                    baseProjectName = metadataPluginProjectName;
                    break;
            }

            File.Move(Path.Combine(outDir, baseProjectName + ".csproj"), outProjectFile);
            File.Move(Path.Combine(outDir, baseProjectName + ".sln"), outSolutionFile);
            FileSystem.ReplaceStringInFile(outProjectFile, baseProjectName, normalizedName);
            FileSystem.ReplaceStringInFile(outSolutionFile, baseProjectName, normalizedName);
            return outDir;
        }

        public static string PackageExtension(string extDirectory, string targetPath)
        {
            var dirInfo = new DirectoryInfo(extDirectory);
            var manifestPath = Path.Combine(extDirectory, PlaynitePaths.ExtensionManifestFileName);
            if (!File.Exists(manifestPath))
            {
                throw new Exception($"Manifest file ({PlaynitePaths.ExtensionManifestFileName}) not found!");
            }

            var extInfo = ExtensionInstaller.GetExtensionManifest(manifestPath);
            if (extInfo.Id.IsNullOrEmpty())
            {
                throw new Exception("Cannot package extension, ID is missing!");
            }

            extInfo.VerifyManifest();

            var packedPath = Path.Combine(targetPath, $"{Common.Paths.GetSafePathName(extInfo.Id).Replace(' ', '_')}_{extInfo.Version.ToString().Replace(".", "_")}{PlaynitePaths.PackedExtensionFileExtention}");
            FileSystem.PrepareSaveFile(packedPath);
            var ignoreFiles = File.ReadAllLines(Paths.ExtFileIgnoreListPath);

            using (var zipStream = new FileStream(packedPath, FileMode.Create))
            {
                using (var zipFile = new ZipArchive(zipStream, ZipArchiveMode.Create))
                {

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Verify extension.yaml actually exists under extDirectory: `ls extDirectory/extension.yaml` (the filename is exactly extension.yaml, not extension.yaml.txt).
  2. Re-run `Toolbox new <type> <name>` to regenerate a valid extension scaffold that includes extension.yaml, then point PackageExtension at that output directory.
  3. Pass the directory that directly contains the manifest, not a parent or sibling directory (PackageExtension does not recurse).
  4. Confirm extDirectory is absolute or resolved against the intended base; relative paths are resolved against the process CWD, which for Toolbox is often unexpected.

Example fix

// before
Extensions.PackageExtension(@".\MyPlugin", outDir); // no extension.yaml here

// after
var extDir = Path.GetFullPath(@".\MyPlugin\source"); // folder containing extension.yaml
if (!File.Exists(Path.Combine(extDir, PlaynitePaths.ExtensionManifestFileName)))
    throw new FileNotFoundException("extension.yaml missing", extDir);
Extensions.PackageExtension(extDir, outDir);
Defensive patterns

Strategy: validation

Validate before calling

var manifestPath = Path.Combine(extDirectory, PlaynitePaths.ExtensionManifestFileName);
if (!File.Exists(manifestPath))
    throw new FileNotFoundException($"extension.yaml not found at {manifestPath}", manifestPath);

Prevention

When it happens

Trigger: Calling PackageExtension(extDirectory, targetPath) where extDirectory points at a folder with no extension.yaml. Common triggers: passing the repository root instead of the built output folder, pointing at the parent of the extension folder, or running `pack` before the manifest file was written by `new`.

Common situations: Switching between an extension's source layout and its deployable layout; building a plugin and pointing Toolbox at /bin output that only has the DLL; cloning a template and renaming/moving extension.yaml; CWD-relative paths that resolve to the wrong directory.

Related errors


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