Significant-Gravitas/AutoGPT · error · ValueError
Workspace {ws_id} does not belong to org {org_id}
Error message
Workspace {ws_id} does not belong to org {org_id} What it means
Raised by team_db.add_team_member when the Team row for ws_id is missing OR its orgId differs from the passed org_id. One guard covering both conditions: the workspace must exist and belong to the organization you are adding within. Plain ValueError from the DB layer.
Source
Thrown at autogpt_platform/backend/backend/api/features/orgs/team_db.py:163
where={"teamId": ws_id, "status": "ACTIVE"},
include={"User": True},
)
return [TeamMemberResponse.from_db(m) for m in members]
async def add_team_member(
ws_id: str,
user_id: str,
org_id: str,
is_admin: bool = False,
is_billing_manager: bool = False,
invited_by: str | None = None,
) -> TeamMemberResponse:
"""Add a member to a workspace. Must be an org member, workspace must belong to org."""
# Verify workspace belongs to the org
ws = await prisma.team.find_unique(where={"id": ws_id})
if ws is None or ws.orgId != org_id:
raise ValueError(f"Workspace {ws_id} does not belong to org {org_id}")
# Verify user is in the org
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")
member = await prisma.teammember.create(
data={
"teamId": ws_id,
"userId": user_id,
"isAdmin": is_admin,
"isBillingManager": is_billing_manager,
"status": "ACTIVE",
"invitedByUserId": invited_by,
},
include={"User": True},View on GitHub (pinned to 9c8bb5550f)
Solutions
- Re-fetch the workspace through GET /api/orgs/{org_id}/workspaces/{ws_id} before showing the add-member form; failure means the pair is invalid
- Build the add-member URL from one TeamResponse (orgId + id) so the pair cannot diverge
- On failure, refresh the admin's workspace list — the workspace may have been deleted or moved
- In tests, create the workspace with create_team(org_id, ...) so orgId matches by construction
Example fix
// before
const url = `/api/orgs/${orgId}/workspaces/${selectedWsId}/members`;
// after
const ws = await getWorkspace(orgId, selectedWsId); // throws first if mismatch
const url = `/api/orgs/${ws.orgId}/workspaces/${ws.id}/members`; Defensive patterns
Strategy: validation
Validate before calling
const ws = await getWorkspace(orgId, wsId).catch(() => null);
if (!ws || ws.orgId !== orgId) throw new Error('Invalid org/workspace pair'); Type guard
function workspaceInOrg(ws: TeamResponse, orgId: string): boolean {
return ws.orgId === orgId;
} Try / catch
try {
await addTeamMember(orgId, wsId, userId);
} catch (e) {
if (e.message.includes('does not belong to org')) {
// refresh admin workspace picker; pair is stale
} else throw e;
} Prevention
- Derive org/ws ids from one TeamResponse when building add-member URLs
- Re-fetch on org switch
When it happens
Trigger: POST /api/orgs/{org_id}/workspaces/{ws_id}/members where ws_id belongs to another org or does not exist. Note the condition is ws is None or ws.orgId != org_id — an already-deleted workspace produces the same 'does not belong' wording rather than a NotFoundError.
Common situations: Admin UI where the org dropdown and workspace picker hold unrelated selections; concurrent deletion of the workspace between list and submit; fixtures pairing a workspace from org A with org B's id.
Related errors
- Cannot remove the last workspace admin. Promote another memb
- Cannot change the default workspace's join policy
- Cannot delete the default workspace
- Workspace does not belong to this organization
- Cannot self-join a PRIVATE workspace. Request an invite.
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/ef741da3426ec7c5.
Report an issue: GitHub.