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

  1. Read `validation.error` to see which structural check failed and fix the package's manifest/entry files at the source
  2. Verify the package repo matches the current pkg package format (manifest + entry point present)
  3. Re-publish or point the registry at a corrected version/tag of the package
  4. 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

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


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)