paperclipai/paperclip · error

workspaceId and companyId are required

Error message

workspaceId and companyId are required

What it means

Thrown by the workspace-diff plugin's `workspace-diff` data source (worker.ts:54) when either `workspaceId` or `companyId` is missing after `readString` trims them. Both identifiers are required because the diff must resolve the workspace and scope it to a company before computing git changes.

Source

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

    : workspaces.find((candidate) => candidate.isPrimary) ?? workspaces[0] ?? null;
  return projectWorkspace
    ? resolveDefaultBaseRef({
      projectWorkspaceDefaultRef: projectWorkspace.defaultRef,
      projectWorkspaceRepoRef: projectWorkspace.repoRef,
    })
    : null;
}

const plugin = definePlugin({
  async setup(ctx) {
    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,

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Supply both `workspaceId` and `companyId` as non-empty trimmed strings in the data-source params.
  2. Defer the diff fetch until the active workspace and company are both resolved in the UI/agent context.
  3. If building params dynamically, assert the two fields are present before invoking the data source.

Example fix

// before
ctx.data.fetch("workspace-diff", { entityType: "project_workspace", projectId });
// after
ctx.data.fetch("workspace-diff", { entityType: "project_workspace", projectId, workspaceId, companyId });
Defensive patterns

Strategy: validation

Validate before calling

function buildWorkspaceDiffParams(input) {
  const workspaceId = typeof input.workspaceId === "string" ? input.workspaceId.trim() : "";
  const companyId = typeof input.companyId === "string" ? input.companyId.trim() : "";
  if (!workspaceId || !companyId) {
    throw new TypeError("workspace-diff requires non-empty workspaceId and companyId");
  }
  return { ...input, workspaceId, companyId };
}

Type guard

function hasWorkspaceDiffIds(p): p is { workspaceId: string; companyId: string } {
  return typeof p?.workspaceId === "string" && p.workspaceId.trim().length > 0
    && typeof p?.companyId === "string" && p.companyId.trim().length > 0;
}

Prevention

When it happens

Trigger: Calling the `workspace-diff` data source with `workspaceId` and/or `companyId` omitted, blank, or non-string. The check runs before any entityType branching, so it applies to both execution-workspace and project-workspace diff requests.

Common situations: A board diff widget is rendered before the workspace context loads (workspaceId still null), a company scope was never injected into the params, or the caller passed the ids under different key names.

Related errors


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