hcengineering/platform · error
Invalid workspace
Error message
Invalid workspace
What it means
The API returns 401 'Invalid workspace' when the token decodes fine, the workspace-info cache misses, and the account service's getLoginWithWorkspaceInfo() contains no membership entry for the workspace named in the URL, while the caller is not an admin. The service only lets non-admin users fetch backups of workspaces they belong to.
Source
Thrown at services/backup/backup-api-pod/src/server.ts:190
res.status(401).end('Unauthorized')
return
}
workspaceId = decoded.workspace
isAdmin = decoded.extra?.admin === 'true'
} catch (err: any) {
res.status(401).end('Unauthorized')
return
}
let wsInfo: WorkspaceIds | undefined = wsInfoCache.get(workspaceId)
const accountClient = getClient(config.AccountsUrl, token)
if (wsInfo === undefined) {
try {
const info = await accountClient.getLoginWithWorkspaceInfo()
const winfo = info.workspaces[workspaceId]
if (!isAdmin) {
if (winfo === undefined) {
res.status(401).end('Invalid workspace')
return
} else {
if (winfo.role !== AccountRole.Owner) {
res.status(401).end('Not an owner of workspace')
return
}
}
}
const wssInfo = await accountClient.getWorkspaceInfo()
wsInfo = {
url: wssInfo.url,
dataId: wssInfo.dataId,
uuid: workspaceId
}
wsInfoCache.set(workspaceId, wsInfo)
} catch (err: any) {
res.status(401).end('Invalid workspace')
returnView on GitHub (pinned to 63e28dc964)
Solutions
- Verify the workspace UUID in the URL matches a workspace the token's account belongs to
- Ask a workspace owner to add your account to the workspace
- Use a token belonging to a member of the target workspace
- If you should be an admin, ensure the token's extra payload includes admin='true'
Example fix
// before
const res = await fetch(`/api/backup/${wrongUuid}/backup.json.gz`)
// after
const res = await fetch(`/api/backup/${myWorkspaceUuid}/backup.json.gz`, { headers: { Authorization: `Bearer ${token}` } }) Defensive patterns
Strategy: validation
Validate before calling
const info = await accountClient.getLoginWithWorkspaceInfo()
if (!isAdmin && info.workspaces[workspaceUuid] === undefined) {
throw new Error(`Not a member of workspace ${workspaceUuid}`)
} Type guard
function canAccessWorkspace(info: { workspaces: Record<string, unknown> }, wsId: string, isAdmin: boolean): boolean {
return isAdmin || info.workspaces[wsId] !== undefined
} Try / catch
try { ... } catch (e) {
if (e.message === 'Invalid workspace') console.error('Check workspace UUID and membership')
throw e
} Prevention
- Copy workspace UUIDs from the account service, not by hand
- Confirm membership before invoking backup downloads
- Use a token of an account that belongs to the target workspace
- List available workspaces from getLoginWithWorkspaceInfo first
When it happens
Trigger: GET /api/backup/<workspaceUuid>/<file> where workspaceUuid in the path is not a key of info.workspaces returned by the account client for that token, and decoded.extra?.admin !== 'true'.
Common situations: Typing or pasting the wrong workspace UUID in the URL, using a personal token for a workspace the user was removed from, or hitting the backup API before being added to the workspace.
Related errors
- platform.status.Unauthorized
- Unauthorized
- Couldn't find workspace with the provided token
- Social ID is missing
- Unauthorized
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/12e5603c9b99dfef.
Report an issue: GitHub.