can1357/oh-my-pi · error · Error
package.json not found at ${absolutePath}
Error message
package.json not found at ${absolutePath} What it means
PluginManager.loadFromPath (or similar install entry) reads <pluginDir>/package.json to get the plugin's name, version, and optional omp/pi manifest. If the file does not exist (ENOENT), it throws this error rather than a raw JSON parse error, so the developer knows the plugin directory itself lacks a package.json. It is a guard against installing a directory that is not a valid npm-style plugin package.
Source
Thrown at packages/coding-agent/src/extensibility/plugins/manager.ts:779
plugins.push(plugin);
}
}
return plugins;
}
/**
* Link a local plugin for development.
*/
async link(localPath: string): Promise<InstalledPlugin> {
const absolutePath = path.resolve(this.#cwd, localPath);
const pkgFilePath = path.join(absolutePath, "package.json");
let pkg: { name?: string; version: string; omp?: PluginManifest; pi?: PluginManifest };
try {
pkg = await Bun.file(pkgFilePath).json();
} catch (err) {
if (isEnoent(err)) throw new Error(`package.json not found at ${absolutePath}`);
throw err;
}
if (!pkg.name) {
throw new Error("package.json must have a name field");
}
await this.#ensurePluginsDir();
const linkPath = path.join(getPluginsNodeModules(), pkg.name);
// Handle scoped packages
if (pkg.name.startsWith("@")) {
const scopeDir = path.join(getPluginsNodeModules(), pkg.name.split("/")[0]);
await fs.promises.mkdir(scopeDir, { recursive: true });
}
// Remove existing
try {View on GitHub (pinned to 9690622007)
Solutions
- Verify the directory actually contains package.json at its root (ls <dir>/package.json).
- Correct the path passed to the install/load call — point at the package root, not a parent or subfolder.
- If authoring a plugin, add a package.json with name, version, and an omp (or pi) manifest field.
- Check the working directory relative to which the path was resolved.
Example fix
// before
await manager.installFromPath("./my-plugin/dist"); // no package.json in dist
// after
await manager.installFromPath("./my-plugin"); // package root Defensive patterns
Strategy: validation
Validate before calling
import * as fs from "node:fs";
const pkgPath = path.join(pluginDir, "package.json");
if (!fs.existsSync(pkgPath)) {
throw new Error(`Not a plugin package: ${pkgPath} missing`);
} Type guard
function hasPackageJson(dir: string): boolean {
try { return fs.statSync(path.join(dir, "package.json")).isFile(); }
catch { return false; }
} Try / catch
try {
await manager.installFromPath(dir);
} catch (err) {
if (err instanceof Error && err.message.includes("package.json not found")) {
console.error(`Directory ${dir} is not a plugin package root`);
} else throw err;
} Prevention
- Always pass the package root directory, not a parent or build-output subfolder
- Check for package.json existence before invoking install APIs
- Scaffold plugins from a template that includes package.json
- Resolve relative paths against a known base directory
When it happens
Trigger: Calling a PluginManager public method that installs/links a plugin from a local path where no package.json exists at the directory root; pointing the installer at a source folder, a git checkout root, or a typo'd directory name.
Common situations: Typo in the plugin path; running the installer against a repo subdirectory instead of the package root; a plugin authored without package.json; path resolved relative to the wrong working directory.
Related errors
- cannot stat {0}: No such file or directory
- File not found: ${pathArg}
- Package installed but package.json not found at ${pkgPath}
- package.json not found at ${absolutePath}
- package.json must have a name field
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/feb542d600cd75b2.
Report an issue: GitHub.