hcengineering/platform · error

Accounts URL or token is not defined

Error message

Accounts URL or token is not defined

What it means

getIntegrationClient in gmail-resources builds an authenticated IntegrationClient for the Gmail integration. It requires both the AccountsUrl (login.metadata.AccountsUrl) and the current session token (presentation.metadata.Token) metadata; if either is undefined it throws 'Accounts URL or token is not defined'.

Source

Thrown at plugins/gmail-resources/src/api.ts:31

// limitations under the License.
//
import { getMetadata } from '@hcengineering/platform'
import presentation from '@hcengineering/presentation'
import login from '@hcengineering/login'
import { type GmailSyncState, gmailIntegrationKind } from '@hcengineering/gmail'
import {
  getIntegrationClient as getIntegrationClientRaw,
  type IntegrationClient,
  request as httpRequest
} from '@hcengineering/integration-client'

import gmail from './plugin'

export async function getIntegrationClient (): Promise<IntegrationClient> {
  const accountsUrl = getMetadata(login.metadata.AccountsUrl)
  const token = getMetadata(presentation.metadata.Token)
  if (accountsUrl === undefined || token === undefined) {
    throw new Error('Accounts URL or token is not defined')
  }
  return getIntegrationClientRaw(accountsUrl, token, gmailIntegrationKind, 'gmail')
}

const url = getMetadata(gmail.metadata.GmailURL) ?? ''

async function request (method: 'GET' | 'POST' | 'DELETE', path?: string, body?: any): Promise<any> {
  return await httpRequest({
    baseUrl: url,
    method,
    path,
    token: getMetadata(presentation.metadata.Token),
    body
  })
}

export async function getState (socialId: string): Promise<GmailSyncState | null> {
  return await request('GET', `/state?socialId=${encodeURIComponent(socialId)}`)

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Configure the accounts service URL so login.metadata.AccountsUrl is defined before initializing the integration.
  2. Ensure the user is logged in and presentation.metadata.Token is set before requesting the integration client.
  3. Defer integration client creation until after authentication completes (login event / auth ready state).
  4. Log which of the two values is undefined to distinguish config vs session problems.

Example fix

// before
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
const token = getMetadata(presentation.metadata.Token)
if (accountsUrl === undefined || token === undefined) {
  throw new Error('Accounts URL or token is not defined')
}
// after
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
const token = getMetadata(presentation.metadata.Token)
if (accountsUrl === undefined || token === undefined) {
  throw new Error(`Accounts URL or token is not defined (accountsUrl: ${accountsUrl === undefined ? 'missing' : 'ok'}, token: ${token === undefined ? 'missing' : 'ok'})`)
}
Defensive patterns

Strategy: validation

Validate before calling

const accountsUrl = getMetadata(login.metadata.AccountsUrl)
const token = getMetadata(presentation.metadata.Token)
if (accountsUrl === undefined) {
  throw new Error('Gmail integration requires login.metadata.AccountsUrl to be configured')
}
if (token === undefined) {
  throw new Error('Gmail integration requires an authenticated session token')
}
const client = await integrationClient()

Type guard

function hasAuthMetadata (m: { accountsUrl: string | undefined, token: string | undefined }): m is { accountsUrl: string, token: string } {
  return m.accountsUrl !== undefined && m.token !== undefined
}

Try / catch

try {
  const client = await integrationClient()
  // use client
} catch (err) {
  if (err instanceof Error && err.message === 'Accounts URL or token is not defined') {
    console.error('Gmail integration misconfigured: check accounts URL config and login state')
    return
  }
  throw err
}

Prevention

When it happens

Trigger: Calling integrationClient/getIntegrationClient before login metadata is populated, in a deployment where login.metadata.AccountsUrl is never configured, or in a session with no token (guest/not authenticated).

Common situations: Missing accounts service URL in app configuration (config/env not wired); integration invoked at startup before authentication completes; token cleared after logout; running the integration in tests without metadata setup.

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