sinelaw/fresh · warning
[pkg] Invalid package
Error message
[pkg] Invalid package '${packageName}': ${validation.error} What it means
`editor.warn` from the install flow in pkg.ts:1251: after extracting a downloaded package to `tempDir`, `validatePackage(tempDir, packageName)` reports an invalid structure and the plugin logs `[pkg] Invalid package '${packageName}': ${validation.error}`, calls `packageFailure`, removes the temp dir, and aborts the install (returns false). It means the package archive did not match the expected plugin/theme layout (missing manifest/entry files, wrong name, bad metadata).
Solutions
- Read `validation.error` to see which structural check failed and fix the package's manifest/entry files at the source
- Verify the package repo matches the current pkg package format (manifest + entry point present)
- Re-publish or point the registry at a corrected version/tag of the package
- Clear caches and retry the install in case the download was corrupted
Example fix
// before (package repo)
// repo root has only src/, no pkg manifest
// after
// add manifest at repo root:
// { "name": "my-plugin", "entry": "dist/main.js", "type": "plugin" } Defensive patterns
Strategy: validation
Validate before calling
// caller-side check before install
const manifest = await fetchPackageManifest(registryEntry);
if (!manifest || !manifest.name || !manifest.entry) {
editor.warn(`[pkg] Skipping ${packageName}: missing manifest fields`);
return false;
} Type guard
function isValidPackageShape(pkg) {
return pkg != null && typeof pkg === 'object' && typeof pkg.name === 'string' && pkg.name.length > 0 && typeof pkg.entry === 'string' && pkg.entry.length > 0;
} Try / catch
const ok = await installPackage(name);
if (!ok) {
// installPackage already warned with validation.error and cleaned tempDir
editor.setStatus(`Install of ${name} failed: invalid package structure`);
} Prevention
- Validate package manifests in the registry itself so bad entries are caught at publish time
- Check that the declared entry file exists in the repo before releasing a package
- Pin installs to reviewed tags/versions rather than moving branch heads
- Retry downloads once and re-validate to rule out corrupted archives
When it happens
Trigger: Installing a plugin/theme whose extracted contents fail `validatePackage` — missing or malformed package manifest, entry point absent, name mismatch between manifest and requested `packageName`, or unsupported structure.
Common situations: Registry entry pointing at a repo with no pkg manifest at its root; package renamed/refactored so declared entry files no longer exist; publishing a source-only repo without build artifacts; corrupted/incomplete download extracted to tempDir.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ${built.error}
- project path does not exist
- folder name must not be empty
- empty path
- empty script: pass a file, or pipe the source on stdin
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/049f93bb6c3f4c44.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/plugins/pkg.ts:1251
if (result.exit_code !== 0) {
const errorMsg = gitErrorMessage(result.stderr, "Clone failed");
packageFailure(`Failed to install ${packageName}: ${errorMsg}`);
return false;
}
// Checkout specific version if requested
if (version && version !== "latest") {
const checkoutResult = await checkoutVersion(tempDir, version);
if (!checkoutResult) {
editor.setStatus(`Installed ${packageName} but failed to checkout version ${version}`);
}
}
// Validate package structure
const validation = validatePackage(tempDir, packageName);
if (!validation.valid) {
editor.warn(`[pkg] Invalid package '${packageName}': ${validation.error}`);
packageFailure(`Failed to install ${packageName}: ${validation.error}`);
// Clean up
fsLocal.removePath(tempDir);
return false;
}
const manifest = validation.manifest;
// Use manifest name as the authoritative package name
if (manifest?.name) packageName = manifest.name;
// Determine correct target directory based on actual package type
const actualType = manifest?.type || "plugin";
const correctPackagesDir = actualType === "plugin" ? PACKAGES_DIR
: actualType === "theme" ? THEMES_PACKAGES_DIR
: actualType === "bundle" ? BUNDLES_PACKAGES_DIR
: LANGUAGES_PACKAGES_DIR;
const correctTargetDir = editor.pathJoin(correctPackagesDir, packageName);View on GitHub (pinned to 67894ca546)