hcengineering/platform · error

Missing workspace url in login info

Error message

Missing workspace url in login info

What it means

The payment service rejects a subscribe request (HTTP 401) when the workspace login info fetched via the withLoginInfo middleware does not contain a workspaceUrl. This service needs the workspace's URL to hand to the payment provider when creating a checkout/subscription, so a login record without it is treated as an authentication-context failure. It indicates the workspace's stored login data is incomplete rather than a malformed request.

Source

Thrown at services/payment/pod-payment/src/server.ts:222

        'create-subscription',
        async (ctx) => {
          const workspaceUuid = req.token?.workspace
          const accountUuid = req.token?.account
          const request = req.body as SubscribeRequest
          const loginInfo = req.loginInfo as WorkspaceLoginInfo

          if (accountUuid === undefined) {
            res.status(401).json({ error: 'Missing account in token' })
            return
          }

          if (workspaceUuid === undefined) {
            res.status(401).json({ error: 'Missing workspace in token' })
            return
          }

          if (loginInfo?.workspaceUrl === undefined) {
            res.status(401).json({ error: 'Missing workspace url in login info' })
            return
          }

          if (request.type === undefined || request.plan === undefined) {
            res.status(400).json({ error: 'Missing required fields: type, plan' })
            return
          }

          let createSubResponse: CheckoutResponse

          try {
            createSubResponse = await provider.createSubscription(
              ctx,
              request,
              workspaceUuid,
              loginInfo.workspaceUrl,
              accountUuid
            )

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Backfill the workspace's login record so workspaceUrl is set (or fix the account service to always populate it at workspace creation).
  2. Check that withLoginInfo is resolving login info for the correct workspace UUID from the token; verify no middleware ordering issue yields undefined loginInfo.
  3. If this happens after a version change, run the migration that adds workspace_url to existing workspaces.
  4. As a client, re-register/update the workspace via the account API to regenerate complete login info, then retry the subscribe call.

Example fix

// before (workspace created without login info)
POST /api/v1/subscriptions/ws-123/subscribe
// -> 401 { error: 'Missing workspace url in login info' }

// after (backfill login info first)
await accountClient.upsertWorkspaceLoginInfo({ workspaceUuid: 'ws-123', workspaceUrl: 'https://ws-123.example.com' })
POST /api/v1/subscriptions/ws-123/subscribe // -> 200 CheckoutResponse
Defensive patterns

Strategy: validation

Validate before calling

const info = await accountClient.getWorkspaceLoginInfo(workspaceUuid)
if (info?.workspaceUrl === undefined || info.workspaceUrl === '') {
  throw new Error(`Workspace ${workspaceUuid} has no workspaceUrl; backfill login info before subscribing`)
}

Type guard

function hasWorkspaceUrl(info: WorkspaceLoginInfo | undefined | null): info is WorkspaceLoginInfo & { workspaceUrl: string } {
  return typeof info?.workspaceUrl === 'string' && info.workspaceUrl.length > 0
}

Try / catch

const res = await fetch(url, opts)
if (res.status === 401) {
  const body = await res.json()
  if (body.error === 'Missing workspace url in login info') {
    // backfill login info, then retry once
  }
}

Prevention

When it happens

Trigger: POST /api/v1/subscriptions/:workspace/subscribe where the authenticated token carries a valid workspaceUuid but the WorkspaceLoginInfo record for that workspace (loaded by withLoginInfo) has workspaceUrl === undefined or the loginInfo object itself is missing.

Common situations: Workspaces created before the workspaceUrl field was introduced (schema migration gap); a workspace whose login/registration flow never recorded its public URL; test or seeded workspaces built directly in the DB without login info; account-service outages causing withLoginInfo to return an empty record.

Related errors


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