Significant-Gravitas/AutoGPT · error · NotFoundError
Workspace {ws_id} not found
Error message
Workspace {ws_id} not found What it means
Raised by get_team() in team_db.py when prisma.team.find_unique for ws_id returns null — no Team (workspace) row exists with that id. Raised as NotFoundError (HTTP 404). Callers pass expected_org_id to additionally validate org ownership; this variant is the plain miss.
Source
Thrown at autogpt_platform/backend/backend/api/features/orgs/team_db.py:64
workspaces = await prisma.team.find_many(
where={
"orgId": org_id,
"archivedAt": None,
"OR": [
{"joinPolicy": "OPEN"},
{"Members": {"some": {"userId": user_id, "status": "ACTIVE"}}},
],
},
order={"createdAt": "asc"},
)
return [TeamResponse.from_db(ws) for ws in workspaces]
async def get_team(ws_id: str, expected_org_id: str | None = None) -> TeamResponse:
"""Get workspace details. Validates org ownership if expected_org_id is given."""
ws = await prisma.team.find_unique(where={"id": ws_id})
if ws is None:
raise NotFoundError(f"Workspace {ws_id} not found")
if expected_org_id and ws.orgId != expected_org_id:
raise NotFoundError(f"Workspace {ws_id} not found in org {expected_org_id}")
return TeamResponse.from_db(ws)
async def update_team(ws_id: str, data: dict) -> TeamResponse:
"""Update workspace fields. Guards the default workspace join policy."""
update_data = {k: v for k, v in data.items() if v is not None}
if not update_data:
return await get_team(ws_id)
# Guard: default workspace joinPolicy cannot be changed
if "joinPolicy" in update_data:
ws = await prisma.team.find_unique(where={"id": ws_id})
if ws and ws.isDefault:
raise ValueError("Cannot change the default workspace's join policy")
await prisma.team.update(where={"id": ws_id}, data=update_data)View on GitHub (pinned to 9c8bb5550f)
Solutions
- Verify the id against a fresh team list (list_user_teams) before use.
- Check prisma.team.find_unique(where={'id': ws_id}) directly if the workspace is expected to exist.
- On 404, remove the workspace from local state and redirect to the workspace picker.
Defensive patterns
Strategy: validation
Validate before calling
const teams = await api.get('/api/teams').then(r => r.data);
const exists = teams.some(t => t.id === wsId);
if (!exists) redirectToTeamPicker(); Try / catch
try {
return await get_team(ws_id);
} catch (NotFoundError) {
raise HTTPException(404, 'Workspace no longer exists')
} Prevention
- Use ids only from a freshly fetched team list
- Purge cached workspace ids after deletions
- Redirect to the picker on 404 instead of error loops
When it happens
Trigger: GET/PATCH team endpoints or any get_team(ws_id) call with a deleted workspace id, a typo'd id, or an id from another environment.
Common situations: Frontend caches workspace list after a workspace was deleted; URL parameters from old sessions; test fixtures with hardcoded ids drifting after DB resets.
Related errors
- Workspace {ws_id} not found in org {expected_org_id}
- Execution not found
- job not found
- Organization {org_id} not found
- Invitation {invitation_id} not found
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/d010ec6ebcceb01b.
Report an issue: GitHub.