Significant-Gravitas/AutoGPT · error · ValueError
Workspace does not belong to this organization
Error message
Workspace does not belong to this organization
What it means
Raised by team_db.join_team when the found workspace's orgId does not equal the org_id passed in. It prevents joining a workspace through the wrong organization's URL scope. Plain ValueError from the DB layer.
Source
Thrown at autogpt_platform/backend/backend/api/features/orgs/team_db.py:103
async def delete_team(ws_id: str) -> None:
"""Delete a workspace. Cannot delete the default workspace."""
ws = await prisma.team.find_unique(where={"id": ws_id})
if ws is None:
raise NotFoundError(f"Workspace {ws_id} not found")
if ws.isDefault:
raise ValueError("Cannot delete the default workspace")
await prisma.team.delete(where={"id": ws_id})
async def join_team(ws_id: str, user_id: str, org_id: str) -> TeamResponse:
"""Self-join an OPEN workspace. User must be an org member."""
ws = await prisma.team.find_unique(where={"id": ws_id})
if ws is None:
raise NotFoundError(f"Workspace {ws_id} not found")
if ws.orgId != org_id:
raise ValueError("Workspace does not belong to this organization")
if ws.joinPolicy != "OPEN":
raise ValueError("Cannot self-join a PRIVATE workspace. Request an invite.")
# Verify user is actually an org member
org_member = await prisma.orgmember.find_unique(
where={"orgId_userId": {"orgId": org_id, "userId": user_id}}
)
if org_member is None:
raise ValueError(f"User {user_id} is not a member of the organization")
# Check not already a member
existing = await prisma.teammember.find_unique(
where={"teamId_userId": {"teamId": ws_id, "userId": user_id}}
)
if existing:
return TeamResponse.from_db(ws)
await prisma.teammember.create(View on GitHub (pinned to 9c8bb5550f)
Solutions
- Always derive ws_id and org_id from the same TeamResponse object (its orgId field) when constructing the join URL
- Re-fetch the workspace via GET /api/orgs/{org_id}/workspaces and use the returned id
- In the client, catch this and reset the user's active-org/workspace selection so links are rebuilt consistently
- Audit generated links/emails to embed both ids from one source
Example fix
// before
const url = `/api/orgs/${activeOrgId}/workspaces/${cachedWsId}/join`;
// after
const ws = await getWorkspace(activeOrgId, cachedWsId); // 404/does-not-belong if stale
const url = `/api/orgs/${ws.orgId}/workspaces/${ws.id}/join`; Defensive patterns
Strategy: validation
Validate before calling
const ws = await getWorkspace(orgId, wsId).catch(() => null);
if (!ws || ws.orgId !== orgId) throw new Error('Workspace does not belong to this org'); Type guard
function workspaceInOrg(ws: TeamResponse, orgId: string): boolean {
return ws.orgId === orgId;
} Try / catch
try {
await joinTeam(orgId, wsId);
} catch (e) {
if (e.message.includes('does not belong to this organization')) {
// reset active org/workspace selection and rebuild the URL
} else throw e;
} Prevention
- Always construct org+workspace URL pairs from a single TeamResponse
- Re-validate on org switch
When it happens
Trigger: POST /api/orgs/{org_id}/workspaces/{ws_id}/join where ws_id belongs to a different org than org_id in the path. Typically a URL assembled from mixed sources (org id from one context, workspace id from another), or after a workspace was moved/recreated under another org.
Common situations: Deep links or bookmarks built from a previous org context; multi-org clients where the active org switch did not refresh workspace references; test fixtures that pair unrelated org and workspace ids.
Related errors
- Cannot self-join a PRIVATE workspace. Request an invite.
- User {user_id} is not a member of the organization
- Cannot change the default workspace's join policy
- Cannot delete the default workspace
- Cannot leave the default workspace
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/677598ced27c097a.
Report an issue: GitHub.