{"record":{"id":"74f47c99d7738e35","repo":"paperclipai/paperclip","slug":"workspaceid-and-companyid-are-required","errorCode":null,"errorMessage":"workspaceId and companyId are required","messagePattern":"workspaceId and companyId are required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/plugin-workspace-diff/src/worker.ts","lineNumber":54,"sourceCode":"    : workspaces.find((candidate) => candidate.isPrimary) ?? workspaces[0] ?? null;\n  return projectWorkspace\n    ? resolveDefaultBaseRef({\n      projectWorkspaceDefaultRef: projectWorkspace.defaultRef,\n      projectWorkspaceRepoRef: projectWorkspace.repoRef,\n    })\n    : null;\n}\n\nconst plugin = definePlugin({\n  async setup(ctx) {\n    ctx.logger.info(`${PLUGIN_NAME} plugin setup`);\n    const workspaceDiff = workspaceDiffService();\n\n    ctx.data.register(\"workspace-diff\", async (params: Record<string, unknown>) => {\n      const workspaceId = readString(params.workspaceId);\n      const companyId = readString(params.companyId);\n      if (!workspaceId || !companyId) {\n        throw new Error(\"workspaceId and companyId are required\");\n      }\n\n      if (params.entityType === \"project_workspace\") {\n        const projectId = readString(params.projectId);\n        if (!projectId) {\n          throw new Error(\"projectId is required for project workspace diffs\");\n        }\n        const workspaces = await ctx.projects.listWorkspaces(projectId, companyId);\n        const workspace = workspaces.find((candidate) => candidate.id === workspaceId);\n        if (!workspace) {\n          throw new Error(\"Workspace not found\");\n        }\n        return workspaceDiff.getDiff({\n          id: workspace.id,\n          companyId,\n          cwd: workspace.path,\n          baseRef: resolveDefaultBaseRef({\n            projectWorkspaceDefaultRef: workspace.defaultRef,","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/plugin-workspace-diff/src/worker.ts#L36-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Supply both `workspaceId` and `companyId` as non-empty trimmed strings in the data-source params.","Defer the diff fetch until the active workspace and company are both resolved in the UI/agent context.","If building params dynamically, assert the two fields are present before invoking the data source."],"exampleFix":"// before\nctx.data.fetch(\"workspace-diff\", { entityType: \"project_workspace\", projectId });\n// after\nctx.data.fetch(\"workspace-diff\", { entityType: \"project_workspace\", projectId, workspaceId, companyId });","handlingStrategy":"validation","validationCode":"function buildWorkspaceDiffParams(input) {\n  const workspaceId = typeof input.workspaceId === \"string\" ? input.workspaceId.trim() : \"\";\n  const companyId = typeof input.companyId === \"string\" ? input.companyId.trim() : \"\";\n  if (!workspaceId || !companyId) {\n    throw new TypeError(\"workspace-diff requires non-empty workspaceId and companyId\");\n  }\n  return { ...input, workspaceId, companyId };\n}","typeGuard":"function hasWorkspaceDiffIds(p): p is { workspaceId: string; companyId: string } {\n  return typeof p?.workspaceId === \"string\" && p.workspaceId.trim().length > 0\n    && typeof p?.companyId === \"string\" && p.companyId.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Gate the diff fetch on both workspace and company context being loaded.","Keep param key names exactly workspaceId/companyId.","In tests, always seed both ids."],"tags":["plugin","workspace-diff","validation","param-validation","git"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}