paperclipai/paperclip · error

Project workspace not found

Error message

Project workspace not found

What it means

HTTP 404 from handleProjectWorkspaceRuntimeCommand when the workspaceId in the URL does not match any workspace of the project loaded by svc.getById(id). The project itself was found (otherwise 'Project not found'), but the workspace sub-resource is absent, so the handler stops before the authorization check.

Source

Thrown at server/src/routes/projects.ts:449

      res.json(workspace);
    },
  );

  async function handleProjectWorkspaceRuntimeCommand(req: Request, res: Response) {
    const id = req.params.id as string;
    const workspaceId = req.params.workspaceId as string;
    const action = String(req.params.action ?? "").trim().toLowerCase();
    if (action !== "start" && action !== "stop" && action !== "restart" && action !== "run") {
      res.status(404).json({ error: "Workspace command action not found" });
      return;
    }

    const project = await getAccessibleResource(req, res, svc.getById(id), "Project not found");
    if (!project) return;

    const workspace = project.workspaces.find((entry) => entry.id === workspaceId) ?? null;
    if (!workspace) {
      res.status(404).json({ error: "Project workspace not found" });
      return;
    }
    if (!(await assertRuntimeManageAllowed(req, res, project.companyId))) return;

    const isSharedWorkspace = Boolean(workspace.sharedWorkspaceKey);
    if (
      req.actor.type === "agent"
      && isSharedWorkspace
      && SHARED_WORKSPACE_STOP_AND_RESTART_ACTIONS.has(action)
    ) {
      throw forbidden("Missing permission to manage workspace runtime services");
    }

    await assertCanManageProjectWorkspaceRuntimeServices(db, req, {
      companyId: project.companyId,
      projectWorkspaceId: workspace.id,
    });

View on GitHub (pinned to 01ad858492)

Solutions

  1. Re-fetch the project (GET /api/projects/:id) and use a workspaceId from its current workspaces list.
  2. Confirm the workspaceId belongs to the same project as the :id path parameter.
  3. Recreate the workspace if it was intentionally deleted, then retry with the new ID.
  4. If the workspace exists but isn't returned, check company scoping/filters on the service's getById (actor may not see it).

Example fix

// before
POST /api/projects/p1/workspaces/w_old/runtime/restart   // 404 Project workspace not found
// after
const project = await fetch('/api/projects/p1').then(r => r.json());
const wId = project.workspaces[0].id; // use a live workspace id
POST `/api/projects/p1/workspaces/${wId}/runtime/restart`
Defensive patterns

Strategy: validation

Validate before calling

const project = await getProject(projectId);
const workspace = project?.workspaces?.find(w => w.id === workspaceId);
if (!workspace) throw new Error(`workspace ${workspaceId} not found in project ${projectId}`);

Type guard

function workspaceExists(project, workspaceId) {
  return Boolean(project && Array.isArray(project.workspaces) && project.workspaces.some(w => w && w.id === workspaceId));
}

Try / catch

try {
  return await postRuntimeCommand(projectId, workspaceId, cmd);
} catch (e) {
  if (isNotFound(e)) {
    const fresh = await refreshProject(projectId); // re-list workspaces
    return postRuntimeCommand(projectId, fresh.workspaces[0].id, cmd);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling a project workspace runtime command endpoint with a stale/deleted workspaceId, a workspaceId belonging to a different project, or a typo'd ID — project.workspaces.find(entry => entry.id === workspaceId) returns null.

Common situations: Workspace was deleted after the client cached its ID; client mixes IDs across projects; concurrent project update removed the workspace; copy-paste of workspaceId from another project.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/891251cec6667c06. Report an issue: GitHub.