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
- Backfill the workspace's login record so workspaceUrl is set (or fix the account service to always populate it at workspace creation).
- Check that withLoginInfo is resolving login info for the correct workspace UUID from the token; verify no middleware ordering issue yields undefined loginInfo.
- If this happens after a version change, run the migration that adds workspace_url to existing workspaces.
- 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
- Always create workspaces through the account API that populates login info atomically.
- Add a DB check/constraint or startup audit for workspaces missing workspace_url.
- Run schema migrations before deploying code that depends on new login-info fields.
- In integration tests, assert every fixture workspace has a workspaceUrl.
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.