hcengineering/platform · error · Error

Missing config for attributes: ${missingEnv.join(', ')}

Error message

Missing config for attributes: ${missingEnv.join(', ')}

What it means

The pod-billing config IIFE validates that no Config field is undefined, throwing 'Missing config for attributes' on import. With Port (4040) and UsageUpdateInterval (3600s) defaulted, the error can only be raised by SECRET, ACCOUNTS_URL, DB_URL, or STORAGE_CONFIG being unset.

Source

Thrown at services/billing/pod-billing/src/config.ts:40

  UsageUpdateInterval: number // seconds
}

const parseNumber = (str: string | undefined): number | undefined => (str !== undefined ? Number(str) : undefined)

const config: Config = (() => {
  const params: Partial<Config> = {
    Port: parseNumber(process.env.PORT) ?? 4040,
    Secret: process.env.SECRET,
    AccountsUrl: process.env.ACCOUNTS_URL,
    DbUrl: process.env.DB_URL,
    StorageConfig: process.env.STORAGE_CONFIG,
    UsageUpdateInterval: parseNumber(process.env.USAGE_UPDATE_INTERVAL) ?? 60 * 60
  }

  const missingEnv = (Object.keys(params) as Array<keyof Config>).filter((key) => params[key] === undefined)

  if (missingEnv.length > 0) {
    throw Error(`Missing config for attributes: ${missingEnv.join(', ')}`)
  }

  return params as Config
})()

export default config

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Set the env vars named in the message: SECRET, ACCOUNTS_URL, DB_URL, STORAGE_CONFIG.
  2. Verify DB_URL points at the billing database and SECRET matches the accounts service value.
  3. Check ConfigMap/Secret mounts and exact env key names in the deployment.
  4. Add a local .env with the four vars before starting the pod.

Example fix

// before
DB_URL=postgres://...  # STORAGE_CONFIG missing
// after
SECRET=...
ACCOUNTS_URL=https://accounts.example.com
DB_URL=postgres://billing:5432/billing
STORAGE_CONFIG={"name":"minio","kind":"s3",...}
Defensive patterns

Strategy: validation

Validate before calling

const missing = ['SECRET','ACCOUNTS_URL','DB_URL','STORAGE_CONFIG'].filter((k) => process.env[k] === undefined)
if (missing.length > 0) throw new Error(`Missing config for attributes: ${missing.join(', ')}`)

Type guard

function hasEnv(key: string): boolean {
  return process.env[key] !== undefined
}

Try / catch

try {
  const { default: config } = await import('./config.js')
} catch (err) {
  if ((err as Error).message.startsWith('Missing config for attributes:')) {
    console.error('billing config error:', err.message)
    process.exit(1)
  }
  throw err
}

Prevention

When it happens

Trigger: Importing services/billing/pod-billing/src/config.ts without one of: SECRET, ACCOUNTS_URL, DB_URL, STORAGE_CONFIG. The message lists the Config keys, e.g. 'Secret, DbUrl'.

Common situations: Deploying the billing service without its database URL or storage config; secret not mounted; forgetting ACCOUNTS_URL after moving accounts to a dedicated host; local run without .env.

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/7eb927730e7adaba. Report an issue: GitHub.