nexu-io/open-design · error · Error
design system backing project belongs to another workspace
Error message
design system backing project belongs to another workspace
What it means
Thrown by the design-system backing project preparer when the resolved project's binding carries a `workspaceId` that is set and differs from the requesting principal's `teamId`. This is the cross-workspace contamination guard: a backing project bound under one workspace cannot be moved by a share request originating from another workspace.
Source
Thrown at apps/daemon/src/design-systems/team-project-share.ts:102
* and each remote-project/local-projection pair compensates itself before
* rejecting.
*/
export function createDesignSystemBackingProjectPreparer(
options: CreateDesignSystemBackingProjectPreparerOptions,
): CreateLinkedProjectTeamResourceShareServiceOptions['prepare'] {
return async (resourceId, scope) => {
let projectId = (await options.resolveProjectId(resourceId, scope))?.trim() ?? '';
if ((!projectId || !options.projectExists(projectId)) && options.ensureProjectId) {
projectId = (await options.ensureProjectId(resourceId, scope))?.trim() ?? '';
}
if (!projectId || !options.projectExists(projectId)) {
throw new Error('design system backing project is unavailable');
}
const workspaceId = scope.principal.teamId;
const memberId = scope.principal.memberId;
const binding = options.getProjectBinding(projectId);
if (binding?.workspaceId && binding.workspaceId !== workspaceId) {
throw new Error('design system backing project belongs to another workspace');
}
if (binding?.createdByWorkspaceMemberId !== memberId) {
throw new TeamResourceShareForbiddenError();
}
options.onPrepared?.({ resourceId, projectId, scope });
return {
projectId,
transition: async (visibility) => {
if (visibility === 'team') {
const published = await options.publishProject(projectId, scope);
if (published.version == null) {
throw new Error('design system backing project publish failed');
}
try {
await options.persistVisibility({ projectId, scope, visibility });
} catch (error) {
try {
await options.unpublishProject(projectId, scope);View on GitHub (pinned to 5be4028344)
Solutions
- Confirm the requesting user is acting in the same workspace that owns the backing project binding.
- If the binding workspace is stale due to a migration, correct the binding row so `workspaceId` matches the owning workspace.
- Do not attempt to cross-share a project from another workspace; re-create the design system resource under the correct workspace instead.
Defensive patterns
Strategy: validation
Validate before calling
// Before sharing, confirm workspace ownership:
const binding = getProjectBinding(projectId);
if (binding?.workspaceId && binding.workspaceId !== scope.principal.teamId) {
throw new Error('refusing cross-workspace share');
}
await share(resourceId, scope); Try / catch
try {
await linkedShare.share(resourceId, scope);
} catch (err) {
if (err instanceof Error && /belongs to another workspace/.test(err.message)) {
// re-create the design system under the correct workspace
}
throw err;
} Prevention
- Bind backing projects to a workspace at creation time and never mutate the binding workspace manually.
- Ensure session principal's teamId reflects the workspace the user intends to act in.
- Reject cross-workspace share attempts in the UI before they reach the preparer.
When it happens
Trigger: A share/unshare request whose `scope.principal.teamId` is workspace B, but the backing project binding's `workspaceId` is workspace A (a different, non-empty value).
Common situations: A design system was originally shared under workspace A and is now being operated on from workspace B due to a stale client, a workspace switch, or a binding row that was not migrated. Manual database edits that changed a binding's workspace. A resource id collision resolving to the wrong project.
Related errors
- design system backing project is unavailable
- workspace_resource_share_denied
- design system backing project publish failed
- WORKSPACE_RESOURCE_AUTHORITY_UNAVAILABLE
- WORKSPACE_PROJECT_PERMISSION_DENIED
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/86b51ed6a046e3be.
Report an issue: GitHub.