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
- Verify extension.yaml actually exists under extDirectory: `ls extDirectory/extension.yaml` (the filename is exactly extension.yaml, not extension.yaml.txt).
- Re-run `Toolbox new <type> <name>` to regenerate a valid extension scaffold that includes extension.yaml, then point PackageExtension at that output directory.
- Pass the directory that directly contains the manifest, not a parent or sibling directory (PackageExtension does not recurse).
- 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
- Always pass the directory that directly contains extension.yaml, resolved to an absolute path.
- Assert File.Exists(manifestPath) immediately before calling PackageExtension.
- Treat a missing extension.yaml as a build/scaffold bug, not a runtime condition — fix the source layout.
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
- Manifest file ({PlaynitePaths.ThemeManifestFileName}) not fo
- Cannot package extension, ID is missing!
- Theme changelog not found.
- Source directory does not exist or could not be found: {sour
- Cannot package theme, ID is missing!
AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13).
Data as JSON: /api/errors/c36d38ea07df051e.
Report an issue: GitHub.