paperclipai/paperclip · critical
${payloadLabel} failed service validation and was rolled bac
Error message
${payloadLabel} failed service validation and was rolled back to ${rolledBack.version}, but the rolled-back service also failed to restart. What it means
Thrown by rollbackAfterServiceValidationFailure when, after a newly updated payload fails to start its service, the automatic rollback to the prior version is performed but restarting the rolled-back service also throws. This is the worst-case recovery failure: both the new and the old payload are unable to run the service. The error bundles both the original validation error and the restart error in an AggregateError as `cause`.
Source
Thrown at cli/src/commands/update.ts:159
async function defaultConfirm(message: string): Promise<boolean> {
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
const answer = await p.confirm({ message, initialValue: false });
return !p.isCancel(answer) && answer === true;
}
function emit(options: UpdateOptions, value: Record<string, unknown>, message: string): void { if (options.json) console.log(JSON.stringify(value, null, 2)); else console.log(message); }
async function rollbackAfterServiceValidationFailure(
paths: InstallStorePaths,
restartActiveService: (expectedVersion: string) => Promise<boolean>,
validationError: unknown,
payloadLabel: string,
): Promise<never> {
const rolledBack = await withInstallStoreLock(async () => rollbackManagedInstall(paths), paths);
try {
await restartActiveService(rolledBack.version);
} catch (restartError) {
throw new Error(
`${payloadLabel} failed service validation and was rolled back to ${rolledBack.version}, but the rolled-back service also failed to restart.`,
{ cause: new AggregateError([validationError, restartError]) },
);
}
throw new Error(`${payloadLabel} failed service validation and was rolled back to ${rolledBack.version}.`, { cause: validationError });
}
export async function updateCommand(options: UpdateOptions, overrides: Partial<Dependencies> = {}): Promise<void> {
const paths = overrides.paths ?? resolveInstallStorePaths();
const executablePath = overrides.executablePath ?? process.argv[1] ?? "";
const runCommand = overrides.runCommand ?? execFileAsync;
const mode = detectInstallMode(executablePath, paths);
const manifest = readInstallManifest(paths);
if (options.rollback) {
if (mode !== "managed") throw new Error("--rollback is only available for managed installs.");
if (options.dryRun) { emit(options, { mode, action: "rollback", dryRun: true, target: manifest?.previous[0]?.version ?? null }, `Would roll back to ${manifest?.previous[0]?.version ?? "the previous payload"}.`); return; }
const next = await withInstallStoreLock(async () => rollbackManagedInstall(paths), paths);
const restarted = await (overrides.restartActiveService ?? restartActiveManagedService)(next.version);View on GitHub (pinned to 67001ec6eb)
Solutions
- Inspect the AggregateError cause: both the original validation error and the restart error tell you what is broken system-wide (fix that root cause first).
- Start the database/service manager and confirm the service unit is loadable: `systemctl --user status paperclipai*` / `launchctl list | grep paperclip`.
- Restore the pre-update database backup if the failure is schema/migration related (the old binary cannot start against the migrated DB).
- Manually point the `current` symlink at a known-good payload and `paperclipai service restart`, or reinstall with `paperclipai install`.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await updateCommand(options);
} catch (error) {
if (error instanceof Error && error.message.includes('rolled-back service also failed to restart') && error.cause instanceof AggregateError) {
const [validationErr, restartErr] = error.cause.errors;
// both versions are broken — surface both, restore DB backup, and reinstall a known-good payload
console.error('Validation failure:', validationErr);
console.error('Restart failure:', restartErr);
await restorePreUpdateBackup();
await installCommand({ version: knownGoodVersion });
} else throw error;
} Prevention
- Always let the pre-update backup run (default) so you can restore when both payloads fail.
- Validate new releases on a staging instance before updating production.
- Keep systemd/launchd healthy — a broken service manager makes every version fail to start.
- Pin to a known-good version with `paperclipai update --version` rather than always chasing latest.
When it happens
Trigger: An update (git or npm payload) installs successfully, restartActiveManagedService throws on the new version, rollbackAfterServiceValidationFailure rolls back to manifest.previous[0], and the restart call for that rolled-back version throws too. Reached via the catch blocks around lines 203-211 and 257-265 in updateCommand.
Common situations: System-wide breakage affecting all versions — e.g. systemd/launchd itself broken, port conflict on every version, shared DB schema already migrated and incompatible with the old binary, or corrupted payload directories for both versions.
Related errors
- No managed install was found to roll back.
- No previous managed payload is available for rollback.
- ${payloadLabel} failed service validation and was rolled bac
- --rollback is only available for managed installs.
- The Paperclip database is not running or reachable, so the p
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/0314126c665aa35e.
Report an issue: GitHub.