sinelaw/fresh · warning

[pkg] Package ' ' requires plugin API version , but this…

Error message

[pkg] Package '${packageName}' requires plugin API version ${manifest.fresh.min_api_version}, but this editor only supports version ${currentApi}. Some features may not work. Update Fresh to get the latest plugin API.

What it means

In pkg.ts validatePackage(), if a package manifest declares fresh.min_api_version greater than the editor's current plugin API version (editor.apiVersion()), a compatibility warning is emitted. The package is still accepted — validation does not fail — but some features may misbehave until the editor is updated.

Solutions

  1. Update the Fresh editor to a version whose plugin API is at least manifest.fresh.min_api_version.
  2. If updating is not possible, downgrade the package to a version built for your editor's API.
  3. Contact the package maintainer to lower min_api_version if the package does not actually need newer APIs.
  4. Accept the warning only if you don't rely on the newer plugin API features.

Example fix

// manifest
[fresh]
min_api_version = 5
// editor.apiVersion() = 4 -> update editor, or pin package version built for API 4
Defensive patterns

Strategy: validation

Validate before calling

const manifest = parseToml(fs.readFileSync(pkgManifest, 'utf8'));
const need = manifest?.fresh?.min_api_version ?? 0;
if (need > editor.apiVersion()) console.warn(`update editor: package needs API ${need}, have ${editor.apiVersion()}`);

Type guard

function apiCompatible(manifest, currentApi) { return !(manifest?.fresh?.min_api_version > currentApi); }

Try / catch

const v = validatePackage(dir, name);
if (v.valid && !apiCompatible(v.manifest, editor.apiVersion())) {
  if (!confirm('package may misbehave; install anyway?')) return;
}

Prevention

When it happens

Trigger: Installing or validating any package whose manifest contains fresh.min_api_version newer than the running editor supports; validatePackage is invoked from both the local and registry install paths.

Common situations: Package published against a newer editor release while the user runs an older editor; skipping editor updates for a long time then installing recently published packages; pinning an older editor version in CI.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/54c431b432e36153. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/plugins/pkg.ts:788

  if (!manifest.type) {
    return {
      valid: false,
      error: "Invalid package.json - missing 'type' field (should be 'plugin', 'theme', 'language', or 'bundle')"
    };
  }

  if (manifest.type !== "plugin" && manifest.type !== "theme" && manifest.type !== "language" && manifest.type !== "bundle") {
    return {
      valid: false,
      error: `Invalid package.json - 'type' must be 'plugin', 'theme', 'language', or 'bundle', got '${manifest.type}'`
    };
  }

  // Warn if package requires a newer plugin API version
  if (manifest.fresh?.min_api_version) {
    const currentApi = editor.apiVersion();
    if (manifest.fresh.min_api_version > currentApi) {
      editor.warn(
        `[pkg] Package '${packageName}' requires plugin API version ${manifest.fresh.min_api_version}, ` +
        `but this editor only supports version ${currentApi}. Some features may not work. ` +
        `Update Fresh to get the latest plugin API.`
      );
    }
  }

  // For plugins, validate entry file exists
  if (manifest.type === "plugin") {
    const entryFile = manifest.fresh?.entry || manifest.fresh?.main || `${manifest.name}.ts`;
    const entryPath = editor.pathJoin(packageDir, entryFile);

    if (!fsLocal.fileExists(entryPath)) {
      // Try .js as fallback
      const jsEntryPath = entryPath.replace(/\.ts$/, ".js");
      if (fsLocal.fileExists(jsEntryPath)) {
        return { valid: true, manifest, entryPath: jsEntryPath };
      }

View on GitHub (pinned to 67894ca546)