paperclipai/paperclip · error
Managed install metadata is missing.
Error message
Managed install metadata is missing.
What it means
Thrown by updateCommand on the managed-npm update path when readInstallManifest returned null. By this point the mode is 'managed' (so the executable resolves through the store's current symlink) but no manifest.json exists, meaning the store is in an inconsistent state: a working symlink without the metadata needed to compute the next manifest, channel, or previous[] history.
Source
Thrown at cli/src/commands/update.ts:244
try {
fs.writeFileSync(npmUserConfigPath, `registry=${PUBLIC_NPM_REGISTRY}\n@paperclipai:registry=${PUBLIC_NPM_REGISTRY}\n`, { mode: 0o600 });
await runCommand("npm", args, {
env: {
...process.env,
npm_config_registry: PUBLIC_NPM_REGISTRY,
NPM_CONFIG_REGISTRY: PUBLIC_NPM_REGISTRY,
npm_config_userconfig: npmUserConfigPath,
NPM_CONFIG_USERCONFIG: npmUserConfigPath,
},
maxBuffer: 16 * 1024 * 1024,
});
} finally {
fs.rmSync(npmConfigDir, { recursive: true, force: true });
}
}
emit(options, { mode, action: "update", targetVersion, dryRun: Boolean(options.dryRun), command: ["npm", ...args] }, options.dryRun ? "Dry run complete." : pc.green(`Updated global npm install to ${targetVersion}.`)); return;
}
if (!manifest) throw new Error("Managed install metadata is missing.");
if (comparison === 0) { emit(options, { mode, currentVersion, targetVersion, changed: false }, `paperclipai ${targetVersion} is already active.`); return; }
if (comparison < 0 && options.yes !== true) { const confirmed = await (overrides.confirm ?? defaultConfirm)(`Downgrade paperclipai from ${currentVersion} to ${targetVersion}?`); if (!confirmed) throw new Error("Downgrade cancelled. Re-run with --yes to confirm explicitly."); }
if (options.dryRun) { emit(options, { mode, currentVersion, targetVersion, action: comparison < 0 ? "downgrade" : "update", backup: options.backup !== false, dryRun: true }, `Would ${comparison < 0 ? "downgrade" : "update"} paperclipai ${currentVersion} → ${targetVersion}${options.backup === false ? " without a backup" : " after a database backup"}.`); return; }
if (options.backup !== false) await runPreUpdateBackup(options, overrides.backup ?? (() => dbBackupCommand({})), overrides.hasInstanceData);
const installed = await withInstallStoreLock(async () => {
const payload = await installNpmPayload(targetVersion, runCommand, paths);
const record: InstallRecord = { source: "npm", version: targetVersion, channel: request.channel, payloadPath: payload.payloadPath, installedAt: (overrides.now?.() ?? new Date()).toISOString() };
const next = buildNextManifest(record, manifest); const oldTarget = fs.readlinkSync(paths.currentPath); flipCurrentAtomic(payload.payloadPath, paths);
try { writeInstallManifestAtomic(next, paths); } catch (error) { flipCurrentAtomic(path.resolve(paths.cliRoot, oldTarget), paths); throw error; }
pruneInstallPayloads(next, paths); return payload;
}, paths);
let restarted: boolean;
try {
restarted = await (overrides.restartActiveService ?? restartActiveManagedService)(targetVersion);
} catch (error) {
return rollbackAfterServiceValidationFailure(
paths,
overrides.restartActiveService ?? restartActiveManagedService,View on GitHub (pinned to 67001ec6eb)
Solutions
- Reinstall cleanly: remove the broken store directory and run `paperclipai install` to regenerate both the symlink and manifest.
- Restore manifest.json from a backup into the managed install store root.
- If only the manifest is missing and the payload dir is intact, write a minimal manifest (source, version, channel, payloadPath, previous: []) matching the current symlink target.
Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
import { resolveInstallStorePaths, readInstallManifest } from '../install-store.js';
function managedStoreConsistent(): boolean {
const paths = resolveInstallStorePaths();
return fs.existsSync(paths.cliRoot) && readInstallManifest(paths) !== null;
}
// if (!managedStoreConsistent()) { /* reinstall before update */ } Try / catch
try {
await updateCommand(options);
} catch (error) {
if (error instanceof Error && error.message === 'Managed install metadata is missing.') {
// store is inconsistent — reinstall to regenerate manifest, then retry update
await installCommand(/* ... */);
await updateCommand(options);
} else throw error;
} Prevention
- Never partially delete the managed install store; remove it fully or leave it intact.
- Back up manifest.json alongside the store.
- After copying/migrating a store, verify readInstallManifest returns non-null before updating.
When it happens
Trigger: updateCommand reaches line 244 in managed mode with a null manifest — e.g. the current symlink exists but manifest.json was deleted, or the store was partially reconstructed. Distinct from error 184 which fires inside rollbackManagedInstall; this one fires on the forward-update path.
Common situations: Manifest file removed/renamed by accident. Store migrated/copied without manifest.json. A prior failed update that wrote the symlink but not the manifest. Hand-edited store leaving it inconsistent.
Related errors
- Managed git install metadata is incomplete.
- No managed install was found to roll back.
- No previous managed payload is available for rollback.
- The Paperclip database is not running or reachable, so the p
- Choose only one of --latest, --canary, or --version.
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/2c77a31a36ae117d.
Report an issue: GitHub.