{"record":{"id":"80ad3950341cdd77","repo":"Significant-Gravitas/AutoGPT","slug":"workspace-ws-id-not-found-in-org-expected-org-i","errorCode":null,"errorMessage":"Workspace {ws_id} not found in org {expected_org_id}","messagePattern":"Workspace (.+?) not found in org (.+?)","errorType":"http","errorClass":"NotFoundError","httpStatus":404,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/orgs/team_db.py","lineNumber":66,"sourceCode":"            \"orgId\": org_id,\n            \"archivedAt\": None,\n            \"OR\": [\n                {\"joinPolicy\": \"OPEN\"},\n                {\"Members\": {\"some\": {\"userId\": user_id, \"status\": \"ACTIVE\"}}},\n            ],\n        },\n        order={\"createdAt\": \"asc\"},\n    )\n    return [TeamResponse.from_db(ws) for ws in workspaces]\n\n\nasync def get_team(ws_id: str, expected_org_id: str | None = None) -> TeamResponse:\n    \"\"\"Get workspace details. Validates org ownership if expected_org_id is given.\"\"\"\n    ws = await prisma.team.find_unique(where={\"id\": ws_id})\n    if ws is None:\n        raise NotFoundError(f\"Workspace {ws_id} not found\")\n    if expected_org_id and ws.orgId != expected_org_id:\n        raise NotFoundError(f\"Workspace {ws_id} not found in org {expected_org_id}\")\n    return TeamResponse.from_db(ws)\n\n\nasync def update_team(ws_id: str, data: dict) -> TeamResponse:\n    \"\"\"Update workspace fields. Guards the default workspace join policy.\"\"\"\n    update_data = {k: v for k, v in data.items() if v is not None}\n    if not update_data:\n        return await get_team(ws_id)\n\n    # Guard: default workspace joinPolicy cannot be changed\n    if \"joinPolicy\" in update_data:\n        ws = await prisma.team.find_unique(where={\"id\": ws_id})\n        if ws and ws.isDefault:\n            raise ValueError(\"Cannot change the default workspace's join policy\")\n\n    await prisma.team.update(where={\"id\": ws_id}, data=update_data)\n    return await get_team(ws_id)\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/orgs/team_db.py#L48-L84","documentation":"Raised by get_team() in team_db.py when the Team row exists but its orgId differs from expected_org_id supplied by the caller. It deliberately returns 'not found' (NotFoundError, HTTP 404) rather than 403 to avoid leaking the existence of workspaces in other organizations.","triggerScenarios":"Accessing /api/orgs/{org_id}/teams/{ws_id} (or any route passing expected_org_id) where the workspace belongs to a different org — cross-tenant probing or a stale link after the workspace moved.","commonSituations":"User is member of multiple orgs and uses a workspace link under the wrong org path; workspace transferred between orgs; frontend builds URLs by concatenating an old org id with a remembered workspace id.","solutions":["Fetch workspaces via the org-scoped list endpoint so ids always come from the same org as the URL.","On 404, re-list the org's workspaces and drop stale ids from client state.","Never construct team URLs by mixing a cached workspace id with a different org id."],"exampleFix":"// before\nrouter.push(`/organizations/${lastOrgId}/teams/${cachedTeamId}`);\n// after\nconst teams = await api.get(`/api/orgs/${activeOrgId}/teams`).then(r => r.data);\nconst team = teams.find(t => t.id === cachedTeamId) ?? teams[0];\nrouter.push(`/organizations/${activeOrgId}/teams/${team.id}`);","handlingStrategy":"validation","validationCode":"const teams = await api.get(`/api/orgs/${activeOrgId}/teams`).then(r => r.data);\nconst inOrg = teams.some(t => t.id === wsId);\nif (!inOrg) redirectToOrgTeamList();","typeGuard":null,"tryCatchPattern":"try {\n  return await get_team(ws_id, expected_org_id=org_id);\n} except NotFoundError:\n  raise HTTPException(404, 'Workspace not found in this organization')","preventionTips":["Always obtain workspace ids from the org-scoped list endpoint","Never combine a cached workspace id with a different org path","Treat 404 as non-existence (by design — it hides cross-org workspaces)"],"tags":["teams","workspaces","not-found","http-404","tenancy"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}