{"record":{"id":"6c62a1b56a0de8f5","repo":"can1357/oh-my-pi","slug":"package-json-not-found-at-absolutepath","errorCode":null,"errorMessage":"package.json not found at ${absolutePath}","messagePattern":"package\\.json not found at (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/plugins/installer.ts","lineNumber":156,"sourceCode":"\n\treturn plugins;\n}\n\nexport async function linkPlugin(localPath: string): Promise<void> {\n\tconst cwd = getProjectDir();\n\tconst absolutePath = path.resolve(cwd, localPath);\n\n\t// Validate that resolved path is within cwd to prevent path traversal\n\tconst normalizedCwd = path.resolve(cwd);\n\tconst normalizedPath = path.resolve(absolutePath);\n\tif (!normalizedPath.startsWith(`${normalizedCwd}/`) && normalizedPath !== normalizedCwd) {\n\t\tthrow new Error(`Invalid path: ${localPath} resolves outside working directory`);\n\t}\n\n\t// Validate package.json exists\n\tconst pkgFile = Bun.file(path.join(absolutePath, \"package.json\"));\n\tif (!(await pkgFile.exists())) {\n\t\tthrow new Error(`package.json not found at ${absolutePath}`);\n\t}\n\n\tlet pkg: { name?: string };\n\ttry {\n\t\tpkg = await pkgFile.json();\n\t} catch (err) {\n\t\tthrow new Error(`Invalid package.json at ${absolutePath}: ${err}`);\n\t}\n\n\tif (!pkg.name || typeof pkg.name !== \"string\") {\n\t\tthrow new Error(\"package.json must have a valid name field\");\n\t}\n\n\t// Validate package name to prevent path traversal via pkg.name\n\tif (pkg.name.includes(\"..\") || pkg.name.includes(\"/\") || pkg.name.includes(\"\\\\\")) {\n\t\t// Exception: scoped packages have one slash\n\t\tif (!pkg.name.startsWith(\"@\") || (pkg.name.match(/\\//g) || []).length !== 1) {\n\t\t\tthrow new Error(`Invalid package name in package.json: ${pkg.name}`);","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/plugins/installer.ts#L138-L174","documentation":"After the path-traversal check, linkPlugin verifies that a package.json exists in the target directory before reading it. This error is thrown when the resolved absolutePath exists but does not contain a package.json, so it cannot be treated as a linkable package.","triggerScenarios":"linkPlugin(localPath, cwd) points at a directory that is not a package root: an empty folder, a source subdirectory (e.g. src/) rather than the package root, a typo'd folder name, or a repo checked out without its package.json.","commonSituations":"Linking the repo root of a monorepo instead of the specific package folder; creating the plugin directory but not running `npm init`/writing package.json yet; .gitignore or checkout rules excluding package.json.","solutions":["Point localPath at the directory containing package.json, not a parent or subdir","Run `npm init -y` (or create package.json manually with a name field) in the target folder","Verify with ls that package.json exists at the resolved path before calling linkPlugin","Check the directory was fully cloned/copied and package.json was not excluded"],"exampleFix":"// before\nawait linkPlugin(\"./my-plugin/src\");\n// after\nawait linkPlugin(\"./my-plugin\");","handlingStrategy":"validation","validationCode":"const abs = path.resolve(cwd, localPath);\nconst stat = await Bun.file(path.join(abs, \"package.json\")).exists();\nif (!stat) throw new Error(`${abs} is not a package root`);","typeGuard":null,"tryCatchPattern":"try {\n\tawait linkPlugin(localPath);\n} catch (err) {\n\tif (err instanceof Error && err.message.startsWith(\"package.json not found\")) {\n\t\t// point at the package root or scaffold a package.json\n\t}\n\tthrow err;\n}","preventionTips":["Always link the folder that directly contains package.json","Scaffold new plugins with a package.json before linking (`npm init -y`)","Verify directory contents when cloning partial/copy-filtered repos"],"tags":["plugins","filesystem","package-json-missing","linking"],"backgroundTag":"package-json-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}