hcengineering/platform · error · PlatformError
account.status.WorkspaceNotFound
account.status.WorkspaceNotFound
Error message
WorkspaceNotFound
What it means
After the permission check, performWorkspaceOperation resolves the requested workspace id(s) via getWorkspacesInfoWithStatusByIds. If the resulting list is empty — i.e. none of the given ids match an existing workspace — it throws account.status.WorkspaceNotFound. It is thrown whenever zero workspaces are found, even if only some ids in a batch are unknown.
Source
Thrown at server/account/src/serviceOperations.ts:146
workspaceId: WorkspaceUuid | WorkspaceUuid[]
event: 'archive' | 'migrate-to' | 'unarchive' | 'delete' | 'reset-attempts'
params: any[]
}
): Promise<boolean> {
const { workspaceId, event, params } = parameters
const { extra, workspace } = decodeTokenVerbose(ctx, token)
if (extra?.admin !== 'true') {
if (event !== 'unarchive' || workspaceId !== workspace) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
}
}
const workspaceUuids = Array.isArray(workspaceId) ? workspaceId : [workspaceId]
const workspaces = await getWorkspacesInfoWithStatusByIds(db, workspaceUuids)
if (workspaces.length === 0) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, {}))
}
let ops = 0
for (const workspace of workspaces) {
const update: Partial<WorkspaceStatus> = {}
switch (event) {
case 'reset-attempts':
update.processingAttempts = 0
update.lastProcessingTime = Date.now() - processingTimeoutMs // To not wait for next step
break
case 'delete':
if (workspace.status.mode !== 'active') {
throw new PlatformError(unknownError('Delete allowed only for active workspaces'))
}
update.mode = 'pending-deletion'
update.processingAttempts = 0
update.processingProgress = 0View on GitHub (pinned to 63e28dc964)
Solutions
- Verify the workspace id exists by fetching workspace info (or listing workspaces) before performing the operation; correct any typo.
- If the workspace was deleted, recreate it or drop the operation — it cannot be archived/unarchived/deleted again.
- Confirm you are calling the account service instance/region that actually hosts the workspace.
- For batch calls, pre-validate all ids and remove nonexistent ones, or split into per-workspace calls so one bad id doesn't abort the batch.
Example fix
// before — blindly operating on a cached id
await client.performWorkspaceOperation(ctx, adminToken, { workspaceId: cachedId, event: 'unarchive', params: {} })
// after — verify existence first
const ws = await getWorkspacesInfoWithStatusByIds(db, [cachedId])
if (ws.length === 0) throw new WorkspaceNotFound(cachedId)
await client.performWorkspaceOperation(ctx, adminToken, { workspaceId: cachedId, event: 'unarchive', params: {} }) Defensive patterns
Strategy: validation
Validate before calling
const ids = Array.isArray(workspaceId) ? workspaceId : [workspaceId]
if (ids.length === 0) throw new Error('workspaceId required')
const found = await getWorkspacesInfoWithStatusByIds(db, ids)
if (found.length !== ids.length) {
throw new Error(`Unknown workspace ids: ${ids.filter((id) => !found.some((w) => w.uuid === id))}`)
} Type guard
function isWorkspaceId(value: unknown): value is string {
return typeof value === 'string' &&
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)
} Try / catch
try {
await client.performWorkspaceOperation(ctx, token, parameters)
} catch (err) {
if (isPlatformError(err) && err.code === account.status.WorkspaceNotFound) {
// treat as permanent: refresh workspace list from source of truth, drop stale ids
}
throw err
} Prevention
- Resolve workspace ids from the workspace service list API, never from hardcoded or cached values.
- Pre-check existence for each id in batch operations.
- Handle workspace-deleted events to purge stale ids from caches/UI state.
- Validate id format (uuid) before sending to the API.
When it happens
Trigger: Calling performWorkspaceOperation with a workspaceId (or an array whose resolved set returns no rows) that does not exist in the account DB: a deleted workspace, a typo'd/uuid-mangled id, a workspace from a different region/account instance, or an empty array.
Common situations: Stale UI cache referencing a workspace deleted moments ago; test fixtures using hardcoded workspace uuids from another environment (dev vs prod); an id copied with wrong casing/format; cross-cluster migration where workspaces exist in a different account service instance.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- platform.status.WorkspaceNotFound
- account.status.WorkspaceNotFound
- WorkspaceNotFound
- WorkspaceNotFound
- Workspace ${options.workspace} not found
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/f6c05a544af90857.
Report an issue: GitHub.