hcengineering/platform · error

Billing url not specified

Error message

Billing url not specified

What it means

billing-client's getClient factory requires a billing service URL to construct a BillingClient. The URL is validated against undefined, null, and empty string; failing all three means the caller has no endpoint configured, so the client refuses to instantiate. This fails fast instead of producing confusing network errors later.

Solutions

  1. Set the billing service URL (e.g. process.env.BILLING_URL) and pass it as the first argument to getClient.
  2. Validate config at startup so missing URL is reported before the client is needed.
  3. Use a config schema (e.g. zod/env-schema) to require the billing URL.

Example fix

// before
const client = getClient(process.env.BILLING_URL, token)
// after
if (!process.env.BILLING_URL) throw new Error('BILLING_URL is required')
const client = getClient(process.env.BILLING_URL, token)
Defensive patterns

Strategy: validation

Validate before calling

const billingUrl = process.env.BILLING_URL
if (!billingUrl) throw new Error('BILLING_URL env var is required')

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.trim().length > 0
}

Prevention

When it happens

Trigger: Calling getClient() with no args, or passing an empty string or null as billingUrl — typically when the URL comes from an unset config variable.

Common situations: Missing BILLING_URL env var in deployment config; config loader returning '' as default; forgetting to pass the URL after a refactor of the factory signature.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at packages/billing-client/src/client.ts:18

import { concatLink, WorkspaceUuid } from '@hcengineering/core'
import { BillingError, NetworkError } from './error'
import {
  AiTokensData,
  AiTranscriptData,
  BillingStats,
  DatalakeStats,
  LiveKitEgressData,
  LiveKitEgressStats,
  LiveKitSessionData,
  LiveKitSessionsStats,
  LiveKitStats
} from './types'

/** @public */
export function getClient (billingUrl?: string, token?: string): BillingClient {
  if (billingUrl === undefined || billingUrl == null || billingUrl === '') {
    throw new Error('Billing url not specified')
  }
  if (token === undefined || token == null || token === '') {
    throw new Error('Token not specified')
  }

  return new BillingClient(billingUrl, token)
}

export class BillingClient {
  private readonly headers: Record<string, string>

  constructor (
    private readonly endpoint: string,
    private readonly token: string
  ) {
    this.headers = {
      Authorization: 'Bearer ' + token,
      'Content-Type': 'application/json'

View on GitHub (pinned to 63e28dc964)