What happened?
resolveInstallContext() in src/hooks/auto-update-checker/cache.ts assumes the cache install directory always has a root-level package.json. When it's missing — e.g. OpenCode's plugin cache extracts only node_modules/ without a root package.json — preparePackageUpdate() returns null and the user sees: "Auto-update could not prepare the active install." even though ~/.cache/opencode/packages/ is writable.
Root cause
In resolveInstallContext() (line 166451 in the built dist/index.js):
function resolveInstallContext(runtimePackageJsonPath) {
if (runtimePackageJsonPath) {
const packageDir = dirname(runtimePackageJsonPath); // → .../opencode-magic-context
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME); // → .../.cache/.../node_modules
if (nodeModulesDir && basename(nodeModulesDir) === "node_modules") {
const installDir = dirname(nodeModulesDir); // → .../opencode-magic-context@latest/
const packageJsonPath = join(installDir, "package.json"); // → .../package.json ← DOES NOT EXIST
if (existsSync(packageJsonPath)) // FAILS HERE
return { installDir, packageJsonPath };
}
return null; // ← returns null; legacy fallback is NEVER reached
}
// This legacy fallback (packages/package.json) is unreachable because
// runtimePackageJsonPath is always truthy when found from the module location
const legacyPackageJsonPath = join(dirname(CACHE_DIR), "package.json");
if (existsSync(legacyPackageJsonPath)) { ... }
return null;
}
Two issues:
-
Missing package.json aborts the entire path. The primary install context check returns null immediately when the root package.json is missing, even though node_modules/ exists and npm install could still proceed.
-
Legacy fallback is unreachable. Because runtimePackageJsonPath is always truthy (found from the runtime module's own package.json), the legacy fallback path (packages/package.json) at the bottom of the function is dead code under this condition.
Suggested improvements
- If the primary path finds
node_modules/ but no root package.json, create one instead of returning null:
if (!existsSync(packageJsonPath)) {
writeFileSync(packageJsonPath, JSON.stringify({ private: true, dependencies: {} }, null, 2));
}
return { installDir, packageJsonPath };
- Or fall through to the legacy path instead of the early
return null.
Environment
- Plugin version: 0.18.0 (trying to update to 0.19.0)
- Cache path:
~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/ (contains only node_modules/, no package.json)
- OpenCode TUI (CLI), linux x64
~/.cache/opencode mount is rw btrfs
What happened?
resolveInstallContext()insrc/hooks/auto-update-checker/cache.tsassumes the cache install directory always has a root-levelpackage.json. When it's missing — e.g. OpenCode's plugin cache extracts onlynode_modules/without a rootpackage.json—preparePackageUpdate()returnsnulland the user sees: "Auto-update could not prepare the active install." even though~/.cache/opencode/packages/is writable.Root cause
In
resolveInstallContext()(line 166451 in the builtdist/index.js):Two issues:
Missing
package.jsonaborts the entire path. The primary install context check returnsnullimmediately when the rootpackage.jsonis missing, even thoughnode_modules/exists andnpm installcould still proceed.Legacy fallback is unreachable. Because
runtimePackageJsonPathis always truthy (found from the runtime module's ownpackage.json), the legacy fallback path (packages/package.json) at the bottom of the function is dead code under this condition.Suggested improvements
node_modules/but no rootpackage.json, create one instead of returningnull:return null.Environment
~/.cache/opencode/packages/@cortexkit/opencode-magic-context@latest/(contains onlynode_modules/, nopackage.json)~/.cache/opencodemount isrwbtrfs