hcengineering/platform · error · PlatformError
Archiving allowed only for active workspaces
Error message
Archiving allowed only for active workspaces
What it means
The 'archive' branch of performWorkspaceOperation only allows archiving workspaces whose status.mode satisfies isActiveMode. Archiving is a lifecycle transition from an active state to 'archiving-pending-backup'; issuing it against a workspace in any other mode (archived, pending-deletion, suspended, transitional) throws unknownError('Archiving allowed only for active workspaces').
Source
Thrown at server/account/src/serviceOperations.ts:169
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 = 0
update.lastProcessingTime = Date.now() - processingTimeoutMs // To not wait for next step
break
case 'archive':
if (!isActiveMode(workspace.status.mode)) {
throw new PlatformError(unknownError('Archiving allowed only for active workspaces'))
}
update.mode = 'archiving-pending-backup'
update.processingAttempts = 0
update.processingProgress = 0
update.lastProcessingTime = Date.now() - processingTimeoutMs // To not wait for next step
break
case 'unarchive':
if (event === 'unarchive') {
if (workspace.status.mode !== 'archived') {
throw new PlatformError(unknownError('Unarchive allowed only for archived workspaces'))
}
}
update.mode = 'pending-restore'
update.processingAttempts = 0
update.processingProgress = 0
update.lastProcessingTime = Date.now() - processingTimeoutMs // To not wait for next stepView on GitHub (pinned to 63e28dc964)
Solutions
- Check workspace.status.mode with isActiveMode before issuing event='archive'; skip workspaces already archived or pending-deletion.
- If the workspace is already archived, the goal is achieved — no operation needed.
- If it's stuck in 'archiving-pending-backup', wait for the backup worker or investigate the processing state (reset-attempts can unstick a stalled processor) before re-archiving.
- Make archive requests idempotent client-side: fetch current status and deduplicate concurrent requests.
Example fix
// before — archive unconditionally
await client.performWorkspaceOperation(ctx, adminToken, { workspaceId: wsId, event: 'archive', params: {} })
// after — only archive active workspaces
const [ws] = await getWorkspaceInfo(ctx, adminToken, wsId)
if (isActiveMode(ws.status.mode)) {
await client.performWorkspaceOperation(ctx, adminToken, { workspaceId: wsId, event: 'archive', params: {} })
} Defensive patterns
Strategy: validation
Validate before calling
const [ws] = await getWorkspacesInfoWithStatusByIds(db, [workspaceId])
if (!ws || !isActiveMode(ws.status.mode)) {
throw new Error(`Cannot archive workspace in mode '${ws?.status.mode}'; archive requires an active workspace`)
} Type guard
function isArchivable(ws: { status: { mode: string } } | undefined): ws is { status: { mode: 'active' | 'restoring' } } {
return ws !== undefined && isActiveMode(ws.status.mode)
} Try / catch
try {
await client.performWorkspaceOperation(ctx, token, { workspaceId, event: 'archive', params: {} })
} catch (err) {
if (String(err?.message).includes('Archiving allowed only for active workspaces')) {
// re-fetch status; treat already-archived as success
return
}
throw err
} Prevention
- Re-fetch workspace status right before archiving; never trust stale UI state.
- Make archive flows idempotent — an already-archived workspace is a no-op, not an error.
- Guard scheduled archive jobs to filter on isActiveMode only.
- Serialize concurrent archive/delete requests per workspace to prevent races.
When it happens
Trigger: Calling performWorkspaceOperation with event='archive' on a workspace whose mode is not active — most commonly an already-archived workspace, one already pending deletion, or one stuck in 'archiving-pending-backup' from a previous archive request.
Common situations: Retrying an archive request that already succeeded (workspace now archived or mid-backup); a scheduled job archiving a list of workspaces where some are already archived; UI showing stale status so the user archives twice; concurrent archive/delete operations racing on the same workspace.
Related errors
- Delete allowed only for active workspaces
- Cannot start recording from state: ${state}
- Cannot stop from state: ${state}
- Cannot pause from state: ${state}
- Cannot resume from state: ${state}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/f141f81489ea1a50.
Report an issue: GitHub.