{"record":{"id":"b1839d03c4e3cb10","repo":"hcengineering/platform","slug":"unknown-workspace","errorCode":null,"errorMessage":"Unknown workspace","messagePattern":"Unknown workspace","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/billing/pod-billing/src/billing.ts","lineNumber":199,"sourceCode":"\n  for (const storageConfig of storageConfigs) {\n    if (storageConfig.kind !== 'datalake') {\n      continue\n    }\n    const storageStats = await client.getWorkspaceStats(ctx, workspace)\n    result.count += storageStats.count\n    result.size += storageStats.size\n  }\n\n  return result\n}\n\nfunction getWorkspaceUuid (req: Request): WorkspaceUuid {\n  const { workspace } = req.params\n  if (uuidValidate(workspace)) {\n    return workspace as WorkspaceUuid\n  }\n  throw new Error('Unknown workspace')\n}\n\nfunction parseDateParameters (req: Request): { fromDate: Date, toDate: Date } {\n  let fromDate: Date\n  if (typeof req.query.fromDate === 'string') {\n    fromDate = new Date(Date.parse(req.query.fromDate))\n  } else {\n    fromDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)\n  }\n\n  let toDate: Date\n  if (typeof req.query.toDate === 'string') {\n    toDate = new Date(Date.parse(req.query.toDate))\n  } else {\n    toDate = new Date(Date.now())\n  }\n\n  return { fromDate, toDate }","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/billing/pod-billing/src/billing.ts#L181-L217","documentation":"getWorkspaceUuid validates the :workspace route parameter with uuidValidate; if it is not a valid UUID it throws Error('Unknown workspace'). Any non-UUID workspace path segment is rejected as an unidentifiable workspace.","triggerScenarios":"Request to any billing workspace route with a workspace param that is a slug, name, empty string, or otherwise not a valid UUID (e.g. GET /workspaces/my-team/billing).","commonSituations":"Client uses human-readable workspace names instead of UUIDs; truncated or copy-paste-damaged UUID; URL-encoding issues; old links using legacy identifiers.","solutions":["Pass the workspace UUID (as returned by the workspace API) in the URL, not its name/slug","Look up the UUID from a name via the workspaces listing endpoint before calling billing routes","Validate the param client-side with a UUID regex/validator before building the URL","Check for truncation or encoding corruption of the ID in logs"],"exampleFix":"// before\nfetch(`/workspaces/${workspaceName}/billing`)\n// after\nif (uuidValidate(workspaceUuid)) {\n  fetch(`/workspaces/${workspaceUuid}/billing`)\n}","handlingStrategy":"validation","validationCode":"import { validate as uuidValidate } from 'uuid'\nif (!uuidValidate(workspaceUuid)) {\n  throw new Error(`'${workspaceUuid}' is not a valid workspace UUID`)\n}","typeGuard":"function isWorkspaceUuid(v: unknown): v is WorkspaceUuid {\n  return typeof v === 'string' && uuidValidate(v)\n}","tryCatchPattern":"try {\n  await billing.get(`/workspaces/${workspaceUuid}/...`)\n} catch (err) {\n  if (String(err.response?.data ?? err.message).includes('Unknown workspace')) {\n    // re-resolve the workspace UUID by name before retrying\n  } else throw err\n}","preventionTips":["Store and pass workspace UUIDs, never names or slugs","Validate UUID format in client code before building URLs","Resolve name-to-UUID via the workspace API once and cache it"],"tags":["uuid","request-validation","rest-api"],"backgroundTag":"invalid-identifier-format","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}