hcengineering/platform · error · PlatformError
WorkspaceNotFound
WorkspaceNotFound
Error message
platform.status.WorkspaceNotFound
What it means
PlatformError with status WorkspaceNotFound thrown when the requested workspace does not exist or is disabled. getWorkspaceInfoWithStatusById returns null for an unknown uuid, and an existing workspace that is disabled while in an active mode is treated the same way, with the workspaceUuid included in the status data.
Source
Thrown at server/account/src/operations.ts:2038
if (!skipAssignmentCheck) {
let role = await db.getWorkspaceRole(account, workspaceUuid)
if (role === null && isAdmin) {
role = AccountRole.Admin
}
if (role == null) {
ctx.warn('Not a member of the workspace', { workspaceUuid, account })
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
}
}
const workspace = await getWorkspaceInfoWithStatusById(db, workspaceUuid)
// TODO: what should we return for archived?
if (workspace == null) {
ctx.warn('Workspace not found', { workspaceUuid, account })
throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUuid }))
}
if (workspace.status.isDisabled && isActiveMode(workspace.status.mode)) {
ctx.warn('Workspace is disabled', { workspaceUuid, account })
throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUuid }))
}
if (!isGuest && updateLastVisit && !isAdmin) {
await db.workspaceStatus.update({ workspaceUuid }, { lastVisit: Date.now() })
}
return workspace
}
/**
* Validates the token and returns the decoded account information.
*/
export async function getLoginInfoByToken (View on GitHub (pinned to 63e28dc964)
Solutions
- Verify the workspaceUuid is valid and still exists (fetch the user's workspace list)
- Check with the workspace admin whether the workspace was disabled and request re-enablement
- Remove stale references to deleted workspaces from client state
- Handle WorkspaceNotFound in the client by redirecting to workspace selection
Example fix
// before
const info = await client.getWorkspaceInfo(token, { workspaceUuid: cachedUuid })
// after
try {
const info = await client.getWorkspaceInfo(token, { workspaceUuid: cachedUuid })
} catch (e) {
if (getPlatformStatusCode(e) === platform.status.WorkspaceNotFound) {
await reselectWorkspace() // drop stale id, pick from fresh list
} else throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the workspace still exists in the user's accessible list before the call
const list = await client.getWorkspaces(token)
if (!list.some(w => w.uuid === workspaceUuid)) {
throw new Error(`Workspace ${workspaceUuid} no longer exists or is inaccessible`)
} Type guard
function workspaceExists(w: { uuid: WorkspaceUuid } | null | undefined, id: WorkspaceUuid): w is { uuid: WorkspaceUuid } {
return w != null && w.uuid === id
} Try / catch
try {
const info = await client.getWorkspaceInfo(token, { workspaceUuid })
} catch (e) {
if (getPlatformStatusCode(e) === platform.status.WorkspaceNotFound) {
await purgeStaleWorkspaceAndReselect(workspaceUuid) // deleted or disabled
} else throw e
} Prevention
- Purge cached workspace ids after delete/archive events (webhooks or refetch)
- Surface 'workspace disabled' states to users instead of retrying
- Never hardcode workspace UUIDs; resolve them from an API listing
- Match environment when copying ids between staging and production
When it happens
Trigger: Requesting a workspaceUuid that was deleted/never existed, or one whose status.isDisabled is true while isActiveMode(mode) holds — i.e. an admin-disabled workspace still nominally in active mode.
Common situations: Client cached a workspace id after deletion; workspace archived/deleted by an owner; workspace suspended by admins; typo in the uuid or hard-coded id from another environment.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/3b5de083827a1092.
Report an issue: GitHub.