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

  1. Verify the directory actually contains package.json at its root (ls <dir>/package.json).
  2. Correct the path passed to the install/load call — point at the package root, not a parent or subfolder.
  3. If authoring a plugin, add a package.json with name, version, and an omp (or pi) manifest field.
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/feb542d600cd75b2. Report an issue: GitHub.