thedotmack/claude-mem · warning
[install] Failed to read existing plugin version:
Error message
[install] Failed to read existing plugin version:
What it means
Printed by the installer while it builds the version banner. It first confirms that <marketplaceDir>/plugin/.claude-plugin/plugin.json exists, then runs readFileSync plus JSON.parse on it to learn the already-installed version. When either call throws (truncated or corrupt JSON, EACCES, odd encoding) the warning prints and existingVersion stays undefined, so the banner omits the 'installed vX' / 'reinstall' segment. The install itself is not affected.
Source
Thrown at src/npx-cli/commands/install.ts:1957
if (isInteractive) {
await playBanner();
p.intro(styleText(['bgCyan', 'black'], ' claude-mem install '));
} else {
console.log('claude-mem install');
}
const marketplaceDir = marketplaceDirectory();
const alreadyInstalled = existsSync(join(marketplaceDir, 'plugin', '.claude-plugin', 'plugin.json'));
let existingVersion: string | undefined;
if (alreadyInstalled) {
try {
const existingPluginJson = JSON.parse(
readFileSync(join(marketplaceDir, 'plugin', '.claude-plugin', 'plugin.json'), 'utf-8'),
);
existingVersion = existingPluginJson.version ?? undefined;
} catch (error: unknown) {
console.warn('[install] Failed to read existing plugin version:', error instanceof Error ? error.message : String(error));
}
}
const dot = styleText('dim', '·');
const segments = [`${styleText('bold', 'claude-mem')} ${styleText('cyan', `v${version}`)}`];
if (existingVersion && existingVersion !== version) {
segments.push(`installed ${styleText('yellow', `v${existingVersion}`)}`);
} else if (existingVersion) {
segments.push(styleText('dim', 'reinstall'));
}
log.info(segments.join(` ${dot} `));
// An explicit --provider flag wins over the trial funnel: never pitch,
// email, poll, or override a provider the operator asked for by name.
const trialPairing = options.provider ? null : await promptProTrialOptIn(version);
if (alreadyInstalled) {
if (process.stdin.isTTY) {View on GitHub (pinned to e2d1df569a)
Solutions
- Inspect and validate the file: cat ~/.claude/plugins/marketplaces/thedotmack/plugin/.claude-plugin/plugin.json, then run node with JSON.parse(readFileSync(...)) on it to confirm it parses
- Fix ownership and permissions if it is root-owned: sudo chown -R $(whoami) ~/.claude/plugins/marketplaces/thedotmack
- If the JSON cannot be repaired, run `npx claude-mem uninstall` and install again so a clean plugin.json is written
- Treat the warning as cosmetic if the version banner does not matter: install continues regardless
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'node:fs';
// Before install: confirm the marketplace plugin.json is readable, valid JSON
const pluginJson = `${process.env.HOME}/.claude/plugins/marketplaces/thedotmack/plugin/.claude-plugin/plugin.json`;
try {
JSON.parse(readFileSync(pluginJson, 'utf8'));
} catch {
// repair or delete plugin.json before running `npx claude-mem install`
} Type guard
function isErrnoException(error: unknown): error is NodeJS.ErrnoException {
return error instanceof Error && typeof (error as NodeJS.ErrnoException).code === 'string';
} Prevention
- Keep ~/.claude owned by your user; never run claude-mem install with sudo
- If an install is interrupted, uninstall before reinstalling so plugin.json is rewritten clean
- Treat plugin.json as build output: do not hand-edit it
When it happens
Trigger: Run `npx claude-mem install` (reinstall or upgrade) while plugin.json exists but is unreadable or unparsable: a previously interrupted install left a truncated file, the marketplace directory is root-owned after a one-off sudo install, or the JSON was hand-edited or saved with a broken encoding.
Common situations: Killing an install midway and re-running it; sudo installs leaving root-owned files under ~/.claude/plugins/marketplaces; dotfile sync tools producing partial files; a disk-full condition during an earlier plugin.json write.
Related errors
- claude-mem: could not read ${USER_SETTINGS_PATH} while check
- Missing cwd in PostToolUse hook input for session ${sessionI
- installPluginDependencies: no package.json at ${targetDir}
- generation parse error: ${outcome.reason}
- generation job ${job.id} not found in scope
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/f56f21e4dc77bfa6.
Report an issue: GitHub.