{"record":{"id":"2f69bf4326fe73fc","repo":"hcengineering/platform","slug":"authentication-token-not-specified","errorCode":null,"errorMessage":"Authentication token not specified","messagePattern":"Authentication token not specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/payment-client/src/client.ts","lineNumber":31,"sourceCode":"// limitations under the License.\n//\n\nimport { concatLink, type WorkspaceUuid } from '@hcengineering/core'\nimport { CheckoutResponse, SubscribeRequest, CheckoutStatus, SubscriptionData } from './types'\nimport { PaymentError, NetworkError } from './error'\n\n/**\n * Create a payment client instance\n * @param paymentUrl - URL of the payment service\n * @param token - Authentication token\n * @returns PaymentClient instance\n */\nexport function getClient (paymentUrl?: string, token?: string): PaymentClient {\n  if (paymentUrl === undefined || paymentUrl == null || paymentUrl === '') {\n    throw new Error('Payment service URL not specified')\n  }\n  if (token === undefined || token == null || token === '') {\n    throw new Error('Authentication token not specified')\n  }\n\n  return new PaymentClient(paymentUrl, token)\n}\n\n/**\n * Payment service client\n * Handles all subscription and payment operations\n */\nexport class PaymentClient {\n  private readonly headers: Record<string, string>\n\n  constructor (\n    private readonly endpoint: string,\n    private readonly token: string\n  ) {\n    this.headers = {\n      Authorization: 'Bearer ' + token,","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/packages/payment-client/src/client.ts#L13-L49","documentation":"The `getClient` factory in payment-client throws this Error when the token argument is undefined, null, or an empty string. All payment API calls require an authentication token, so the factory refuses to construct a client without one. This fail-fast validation prevents unauthenticated requests from ever being issued.","triggerScenarios":"Calling `getClient(paymentUrl)` with only a URL, or `getClient(paymentUrl, '')` / `getClient(paymentUrl, undefined)` — the token env var or credential store returned nothing.","commonSituations":"Missing auth token env var (e.g. PAYMENT_TOKEN), expired token that was cleared from a secret store, secret not mounted in the container, or the login/token-fetch step upstream failed silently.","solutions":["Obtain a valid token and pass it as the second argument: `getClient(paymentUrl, token)`.","Ensure the token's environment variable or secret is present in the deployment environment.","Check the upstream process that fetches/refreshes the token — it may have failed and produced an empty string.","Log/inspect the token presence (not its value) before calling getClient to catch empty tokens early."],"exampleFix":"// before\nconst client = getClient(url, process.env.PAYMENT_TOKEN)\n// after\nif (!process.env.PAYMENT_TOKEN) throw new Error('PAYMENT_TOKEN env var required')\nconst client = getClient(url, process.env.PAYMENT_TOKEN)","handlingStrategy":"validation","validationCode":"function assertToken(token: string | undefined | null): asserts token is string {\n  if (token == null || token === '') throw new Error('Payment token missing — check PAYMENT_TOKEN')\n}\nassertToken(process.env.PAYMENT_TOKEN)\nconst client = getClient(paymentUrl, process.env.PAYMENT_TOKEN as string)","typeGuard":"function hasToken(t: unknown): t is string {\n  return typeof t === 'string' && t.trim() !== ''\n}","tryCatchPattern":"try {\n  const client = getClient(url, token)\n} catch (e) {\n  if ((e as Error).message === 'Authentication token not specified') {\n    throw new Error('Config error: payment token missing — refresh credentials')\n  }\n  throw e\n}","preventionTips":["Verify token retrieval/refresh steps actually populated the token before client creation.","Mount secrets correctly in containers and check secret presence at startup.","Never default tokens to empty strings; treat them as required config."],"tags":["authentication","token","payment","configuration"],"backgroundTag":"missing-auth-token","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}