hcengineering/platform · error · ApiError

You do not have write access to the target workspace. Owner

Error message

You do not have write access to the target workspace. Owner role required.

What it means

Export writes data into the target workspace, so the server requires write privileges. This HTTP 403 is thrown when the token is not an admin (decodedToken.extra.admin !== 'true') AND the user's role in the target workspace is not AccountRole.Owner.

Source

Thrown at services/export/pod-export/src/server.ts:528

        }

        // Get target workspace info
        const accountClient = getClient(envConfig.AccountsUrl, token)
        const targetWsLoginInfo = await accountClient.getLoginWithWorkspaceInfo()

        const targetWsInfo = targetWsLoginInfo.workspaces[targetWorkspace]
        if (targetWsInfo === undefined) {
          measureCtx.warn(`Target workspace not found or not accessible: ${targetWorkspace}`)
          throw new ApiError(404, 'Target workspace not found or not accessible')
        }

        // Verify user has write access to target workspace
        const isAdmin: boolean = decodedToken.extra?.admin === 'true'
        if (!isAdmin && targetWsInfo.role !== AccountRole.Owner) {
          measureCtx.warn(
            `User does not have write access to target workspace: ${targetWorkspace}, role: ${targetWsInfo.role}`
          )
          throw new ApiError(403, 'You do not have write access to the target workspace. Owner role required.')
        }

        const targetWsIds: WorkspaceIds = {
          uuid: targetWorkspace,
          dataId: targetWsInfo.dataId,
          url: targetWsInfo.url
        }

        const targetToken = generateToken(decodedToken.account, targetWorkspace, {
          service: 'export'
        })

        // Create clients for both workspaces
        const sourceClient = await createPlatformClient(token)
        const targetClient = await createPlatformClient(targetToken)
        const targetTxOps = new TxOperations(targetClient, socialId)

        try {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Ask the target workspace owner to grant your account the Owner role in that workspace.
  2. Use a token belonging to the target workspace's owner or an admin account (extra.admin='true').
  3. Export into a workspace you own instead.

Example fix

// before
const token = memberAccountToken
// after
const token = workspaceOwnerAccountToken // role: Owner in target workspace
Defensive patterns

Strategy: validation

Validate before calling

const info = await accountClient.getLoginWithWorkspaceInfo()
const ws = info.workspaces[targetWorkspace]
const isAdmin = decodedToken.extra?.admin === 'true'
if (!ws || (!isAdmin && ws.role !== AccountRole.Owner)) {
  throw new Error(`Account needs Owner role (or admin) in ${targetWorkspace}; has: ${ws?.role}`)
}

Type guard

function hasWriteAccess(decoded: DecodedToken, ws: WorkspaceInfo): boolean {
  return decoded.extra?.admin === 'true' || ws.role === AccountRole.Owner
}

Try / catch

try {
  await exportPod({ targetWorkspace })
} catch (err) {
  if (err instanceof ApiError && err.status === 403 && /write access/.test(err.message)) {
    console.error('Re-run with a token whose account owns the target workspace')
  } else throw err
}

Prevention

When it happens

Trigger: Running an export with a token belonging to a user whose role in the target workspace is Member/Guest/Read only, or an unprivileged account without the admin extra flag set to 'true'.

Common situations: Migrations performed by regular users into workspaces owned by someone else; CI/service accounts with only member role; assuming admin of the source workspace grants rights in the target workspace.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/1584fbe27bd2fbcb. Report an issue: GitHub.