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

  1. 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
  2. Fix ownership and permissions if it is root-owned: sudo chown -R $(whoami) ~/.claude/plugins/marketplaces/thedotmack
  3. If the JSON cannot be repaired, run `npx claude-mem uninstall` and install again so a clean plugin.json is written
  4. 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

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


AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20). Data as JSON: /api/errors/f56f21e4dc77bfa6. Report an issue: GitHub.