{"record":{"id":"f6c05a544af90857","repo":"hcengineering/platform","slug":"account-status-workspacenotfound-f6c05a","errorCode":"account.status.WorkspaceNotFound","errorMessage":"WorkspaceNotFound","messagePattern":"WorkspaceNotFound","errorType":"error_code","errorClass":"PlatformError","httpStatus":null,"severity":"error","filePath":"server/account/src/serviceOperations.ts","lineNumber":146,"sourceCode":"    workspaceId: WorkspaceUuid | WorkspaceUuid[]\n    event: 'archive' | 'migrate-to' | 'unarchive' | 'delete' | 'reset-attempts'\n    params: any[]\n  }\n): Promise<boolean> {\n  const { workspaceId, event, params } = parameters\n  const { extra, workspace } = decodeTokenVerbose(ctx, token)\n\n  if (extra?.admin !== 'true') {\n    if (event !== 'unarchive' || workspaceId !== workspace) {\n      throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))\n    }\n  }\n\n  const workspaceUuids = Array.isArray(workspaceId) ? workspaceId : [workspaceId]\n\n  const workspaces = await getWorkspacesInfoWithStatusByIds(db, workspaceUuids)\n  if (workspaces.length === 0) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, {}))\n  }\n\n  let ops = 0\n  for (const workspace of workspaces) {\n    const update: Partial<WorkspaceStatus> = {}\n    switch (event) {\n      case 'reset-attempts':\n        update.processingAttempts = 0\n        update.lastProcessingTime = Date.now() - processingTimeoutMs // To not wait for next step\n        break\n      case 'delete':\n        if (workspace.status.mode !== 'active') {\n          throw new PlatformError(unknownError('Delete allowed only for active workspaces'))\n        }\n\n        update.mode = 'pending-deletion'\n        update.processingAttempts = 0\n        update.processingProgress = 0","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/account/src/serviceOperations.ts#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — blindly operating on a cached id\nawait client.performWorkspaceOperation(ctx, adminToken, { workspaceId: cachedId, event: 'unarchive', params: {} })\n// after — verify existence first\nconst ws = await getWorkspacesInfoWithStatusByIds(db, [cachedId])\nif (ws.length === 0) throw new WorkspaceNotFound(cachedId)\nawait client.performWorkspaceOperation(ctx, adminToken, { workspaceId: cachedId, event: 'unarchive', params: {} })","handlingStrategy":"validation","validationCode":"const ids = Array.isArray(workspaceId) ? workspaceId : [workspaceId]\nif (ids.length === 0) throw new Error('workspaceId required')\nconst found = await getWorkspacesInfoWithStatusByIds(db, ids)\nif (found.length !== ids.length) {\n  throw new Error(`Unknown workspace ids: ${ids.filter((id) => !found.some((w) => w.uuid === id))}`)\n}","typeGuard":"function isWorkspaceId(value: unknown): value is string {\n  return typeof value === 'string' &&\n    /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)\n}","tryCatchPattern":"try {\n  await client.performWorkspaceOperation(ctx, token, parameters)\n} catch (err) {\n  if (isPlatformError(err) && err.code === account.status.WorkspaceNotFound) {\n    // treat as permanent: refresh workspace list from source of truth, drop stale ids\n  }\n  throw err\n}","preventionTips":["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."],"tags":["not-found","workspace","invalid-identifier"],"backgroundTag":"resource-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}