{"record":{"id":"135b45864f87f9ff","repo":"nexu-io/open-design","slug":"workspace-resource-share-denied-135b45","errorCode":null,"errorMessage":"workspace_resource_share_denied","messagePattern":"workspace_resource_share_denied","errorType":"exception","errorClass":"TeamResourceShareForbiddenError","httpStatus":403,"severity":"error","filePath":"apps/daemon/src/design-systems/team-project-share.ts","lineNumber":105,"sourceCode":"export function createDesignSystemBackingProjectPreparer(\n  options: CreateDesignSystemBackingProjectPreparerOptions,\n): CreateLinkedProjectTeamResourceShareServiceOptions['prepare'] {\n  return async (resourceId, scope) => {\n    let projectId = (await options.resolveProjectId(resourceId, scope))?.trim() ?? '';\n    if ((!projectId || !options.projectExists(projectId)) && options.ensureProjectId) {\n      projectId = (await options.ensureProjectId(resourceId, scope))?.trim() ?? '';\n    }\n    if (!projectId || !options.projectExists(projectId)) {\n      throw new Error('design system backing project is unavailable');\n    }\n    const workspaceId = scope.principal.teamId;\n    const memberId = scope.principal.memberId;\n    const binding = options.getProjectBinding(projectId);\n    if (binding?.workspaceId && binding.workspaceId !== workspaceId) {\n      throw new Error('design system backing project belongs to another workspace');\n    }\n    if (binding?.createdByWorkspaceMemberId !== memberId) {\n      throw new TeamResourceShareForbiddenError();\n    }\n    options.onPrepared?.({ resourceId, projectId, scope });\n    return {\n      projectId,\n      transition: async (visibility) => {\n        if (visibility === 'team') {\n          const published = await options.publishProject(projectId, scope);\n          if (published.version == null) {\n            throw new Error('design system backing project publish failed');\n          }\n          try {\n            await options.persistVisibility({ projectId, scope, visibility });\n          } catch (error) {\n            try {\n              await options.unpublishProject(projectId, scope);\n            } catch (rollbackError) {\n              // Remote rollback failed, so the project publication is still\n              // Team-authoritative. Retry the local forward projection once;","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/design-systems/team-project-share.ts#L87-L123","documentation":"Thrown as `TeamResourceShareForbiddenError` (message `workspace_resource_share_denied`) when the backing project binding's `createdByWorkspaceMemberId` does not equal the requesting principal's `memberId`. Linked design-system projects are single-writer: only the original creator is authorized to share or unshare the backing project.","triggerScenarios":"A workspace member who is not the creator of the backing project binding attempts to share or unshare the linked design system. The preparer runs during `prepare()` and rejects before any hub mutation.","commonSituations":"A teammate (admin or otherwise) tries to unshare a design system that another member originally shared. Ownership was never transferred after a member left. A generic hub capability grants broad permissions, but the linked-project policy narrows unshare to the creator.","solutions":["Have the original creator (the member whose id matches `binding.createdByWorkspaceMemberId`) perform the share/unshare.","If ownership must change, update the binding's `createdByWorkspaceMemberId` through an authorized admin path first.","Confirm the request principal (`scope.principal.memberId`) is being set correctly from the authenticated session."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before sharing/unsharing, confirm the requesting member is the creator:\nconst binding = getProjectBinding(projectId);\nif (binding?.createdByWorkspaceMemberId !== scope.principal.memberId) {\n  throw new Error('only the creator may share/unshare this design system');\n}\nawait share(resourceId, scope);","typeGuard":null,"tryCatchPattern":"import { TeamResourceShareForbiddenError } from '../collab/team-resource-share.js';\n\ntry {\n  await linkedShare.share(resourceId, scope);\n} catch (err) {\n  if (err instanceof TeamResourceShareForbiddenError) {\n    // surface 'only the creator can share this design system' to the user\n  }\n  throw err;\n}","preventionTips":["Gate the share/unshare UI action on whether the current member is the resource owner.","Transfer binding ownership explicitly when the creator leaves the workspace.","Never assume admin role implies linked-project unshare rights."],"tags":["team","design-system","workspace","share","authorization","forbidden"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}