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
- Update the Fresh editor to a version whose plugin API is at least manifest.fresh.min_api_version.
- If updating is not possible, downgrade the package to a version built for your editor's API.
- Contact the package maintainer to lower min_api_version if the package does not actually need newer APIs.
- 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
- Keep the editor updated before installing recently published packages.
- Check a package's declared min_api_version against editor.apiVersion() in automated setup scripts.
- Pin package versions compatible with your editor when running older editors (e.g. CI).
- Subscribe to editor release notes for plugin API bumps.
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)