paperclipai/paperclip · error

Workspace not found

Error message

Workspace not found

What it means

Thrown by the workspace-diff plugin (worker.ts:65) in the `project_workspace` branch when `ctx.projects.listWorkspaces(projectId, companyId)` returns a list that contains no workspace whose `id` equals the supplied `workspaceId`. This means the workspace exists in the caller's intent but is not a member of that project under that company.

Source

Thrown at packages/plugins/plugin-workspace-diff/src/worker.ts:65

    ctx.logger.info(`${PLUGIN_NAME} plugin setup`);
    const workspaceDiff = workspaceDiffService();

    ctx.data.register("workspace-diff", async (params: Record<string, unknown>) => {
      const workspaceId = readString(params.workspaceId);
      const companyId = readString(params.companyId);
      if (!workspaceId || !companyId) {
        throw new Error("workspaceId and companyId are required");
      }

      if (params.entityType === "project_workspace") {
        const projectId = readString(params.projectId);
        if (!projectId) {
          throw new Error("projectId is required for project workspace diffs");
        }
        const workspaces = await ctx.projects.listWorkspaces(projectId, companyId);
        const workspace = workspaces.find((candidate) => candidate.id === workspaceId);
        if (!workspace) {
          throw new Error("Workspace not found");
        }
        return workspaceDiff.getDiff({
          id: workspace.id,
          companyId,
          cwd: workspace.path,
          baseRef: resolveDefaultBaseRef({
            projectWorkspaceDefaultRef: workspace.defaultRef,
            projectWorkspaceRepoRef: workspace.repoRef,
          }),
        }, workspaceDiffQuerySchema.parse(params));
      }

      const workspace = await ctx.executionWorkspaces.get(workspaceId, companyId);
      if (!workspace) {
        throw new Error("Workspace not found");
      }
      let projectWorkspaceDefaultBaseRef: string | null = null;
      if (!readOptionalString(workspace.baseRef)) {

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Confirm the workspaceId belongs to the given projectId by listing workspaces first, or refresh the workspace selector.
  2. If the workspace was removed, clear the selection and let the user/agent pick a current one.
  3. Switch entityType to the execution-workspace path if the id is actually an execution workspace, not a project workspace.
Defensive patterns

Strategy: validation

Validate before calling

// Verify the workspace is a member of the project before requesting the diff.
async function workspaceBelongsToProject(ctx, projectId, companyId, workspaceId) {
  const workspaces = await ctx.projects.listWorkspaces(projectId, companyId);
  return workspaces.some((w) => w.id === workspaceId);
}

Try / catch

try {
  await ctx.data.fetch("workspace-diff", params);
} catch (err) {
  if (err instanceof Error && err.message === "Workspace not found") {
    // refresh the project workspace list and re-prompt selection
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the diff data source with `entityType: "project_workspace"`, a valid projectId/companyId, and a workspaceId that is not among the project's workspaces — e.g. a workspace id from a different project, a stale id after the workspace was removed, or a cross-company id.

Common situations: A workspace was deleted or reassigned to another project but the UI/agent still holds the old id; or a workspaceId from an execution-workspace context is mistakenly used in a project_workspace diff request.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/0e77d5a5199e3af5. Report an issue: GitHub.