paperclipai/paperclip · error · HttpError
workspace_repair_precondition_failed
workspace_repair_precondition_failed
Error message
Workspace repair requires a registered base project workspace.
What it means
Thrown by the execution-workspace repair action (POST /execution-workspaces/:id/repair) when the workspace being repaired has no registered base project workspace. The repair flow reseeds a managed worktree's .paperclip database from a seed source that must live inside a registered project workspace checkout, so a missing or cwd-less project workspace row makes repair impossible. It is rethrown as HTTP 422 with code workspace_repair_precondition_failed and reason source_registration_invalid. The projectWorkspace row is looked up from existing.projectWorkspaceId scoped to the same company and project, so a null result means either no projectWorkspaceId was set or the referenced row no longer matches that scope.
Source
Thrown at server/src/routes/execution-workspaces.ts:402
const manifestPath = path.join(workspaceCwd, ".paperclip", "seed-manifest.json");
let manifest: {
attemptId?: unknown;
source?: { configPath?: unknown; instanceId?: unknown };
targetInstanceId?: unknown;
};
try {
manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
} catch {
throw unprocessable("Workspace seed manifest is malformed; repair source identity cannot be trusted.", {
code: "workspace_repair_precondition_failed",
reason: "seed_manifest_malformed",
repairPhase: "precondition_validation",
});
}
try {
if (!projectWorkspace?.cwd) {
throw new Error("Workspace repair requires a registered base project workspace.");
}
const expectedTargetInstanceId = resolveManagedWorkspaceInstanceId(workspaceCwd);
if (!expectedTargetInstanceId) {
throw new Error("Workspace repair cannot resolve the registered target instance.");
}
repairSeedSource = resolveCanonicalWorktreeSeedSource({
registeredBaseWorkspaceCwd: projectWorkspace.cwd,
explicitSourceConfigPath: resolveFallbackSeedSourceConfigPath(projectWorkspace.cwd),
targetConfigPath: path.join(workspaceCwd, ".paperclip", "config.json"),
expectedTargetInstanceId,
manifestSource: manifest.source,
manifestTargetInstanceId: manifest.targetInstanceId,
});
repairPreviousAttemptId = typeof manifest.attemptId === "string" ? manifest.attemptId : null;
const baseWorkspaceCwd = repairSeedSource.baseWorkspaceCwd;
if (!baseWorkspaceCwd) {
throw new Error("Workspace repair source is not bound to a registered base project workspace.");View on GitHub (pinned to a7e689b3c3)
Solutions
- Check the execution workspace record: GET /api/execution-workspaces/:id and confirm projectWorkspaceId is set and non-null.
- Verify the project workspace row exists and has a cwd: query project_workspaces by that id within the same company/project scope and confirm cwd is a non-empty, existing directory.
- Re-register or fix the base project workspace (re-add the checkout so its cwd resolves), then retry the repair action.
- If the base checkout genuinely no longer exists, re-create the execution workspace from a healthy base instead of repairing it.
Example fix
// before
await api.post(`/api/execution-workspaces/${id}/repair`); // 422 workspace_repair_precondition_failed
// after
const ws = await api.getExecutionWorkspace(id);
if (!ws.projectWorkspaceId) throw new Error("Register a base project workspace before repair.");
const base = await api.getProjectWorkspace(ws.projectWorkspaceId);
if (!base?.cwd) throw new Error("Base project workspace has no cwd; re-register it.");
await api.post(`/api/execution-workspaces/${id}/repair`); Defensive patterns
Strategy: validation
Validate before calling
const ws = await api.getExecutionWorkspace(id);
if (!ws.projectWorkspaceId) throw new Error("Execution workspace has no base project workspace; register one before repair.");
const base = await api.getProjectWorkspace(ws.projectWorkspaceId);
if (!base?.cwd || !existsSync(base.cwd)) throw new Error(`Base project workspace cwd missing or absent: ${base?.cwd}`); Type guard
function isRepairReadyWorkspace(ws: { projectWorkspaceId: string | null }, base: { cwd: string | null } | null): boolean {
return Boolean(ws.projectWorkspaceId && base?.cwd);
} Try / catch
try {
await api.post(`/api/execution-workspaces/${id}/repair`);
} catch (err) {
if (err?.status === 422 && err.body?.details?.code === "workspace_repair_precondition_failed" && err.body?.details?.reason === "source_registration_invalid") {
// re-register the base project workspace, then retry
} else throw err;
} Prevention
- Always register the base project workspace (with a real cwd) before creating execution workspaces that may need repair.
- Never delete or move a project workspace checkout while execution workspaces still reference it.
- Monitor the 422 reason field (source_registration_invalid vs seed_manifest_malformed) to distinguish registration problems from manifest corruption.
When it happens
Trigger: Calling the runtime command route with action="repair" on an execution workspace whose projectWorkspaceId is null, or whose project_workspaces row was deleted or has a null/empty cwd (the DB select at server/src/routes/execution-workspaces.ts:291-310 returns null or a row without cwd). Always fires before any operation row or service mutation.
Common situations: Execution workspace created from a project that never registered a local base checkout; the base project workspace was deleted or re-registered after the execution workspace was seeded; a worktree whose parent project workspace record lost its cwd after a move of the repo on disk; company/project scoping mismatch after data imports.
Related errors
- Workspace database repair command timed out during ${repairP
- Workspace database repair command failed during ${repairPhas
- Workspace reseed returned without a verified terminal manife
- Execution workspace needs a local path before Paperclip can
- Managed restart did not produce healthy runtime services.
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21).
Data as JSON: /api/errors/1ba694494f71f392.
Report an issue: GitHub.