{"record":{"id":"3ecbef99dd41bc9f","repo":"hcengineering/platform","slug":"calendar-service-url-or-token-is-not-defined","errorCode":null,"errorMessage":"Calendar service URL or token is not defined","messagePattern":"Calendar service URL or token is not defined","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/calendar-resources/src/api.ts","lineNumber":32,"sourceCode":"//\n\nimport { getMetadata } from '@hcengineering/platform'\nimport presentation from '@hcengineering/presentation'\nimport login from '@hcengineering/login'\nimport { type Integration } from '@hcengineering/account-client'\nimport {\n  type IntegrationClient,\n  getIntegrationClient as getIntegrationClientRaw,\n  request\n} from '@hcengineering/integration-client'\nimport calendar from './plugin'\nimport { calendarIntegrationKind } from '@hcengineering/calendar'\n\nexport async function signout (integration: Integration, client: IntegrationClient): Promise<void> {\n  const url = getMetadata(calendar.metadata.CalendarServiceURL)\n  const token = getMetadata(presentation.metadata.Token)\n  if (url === undefined || token === undefined) {\n    throw new Error('Calendar service URL or token is not defined')\n  }\n  const connection = await client.getConnection(integration)\n  const email = integration.data?.email ?? connection?.data?.email\n  if (email === undefined) {\n    throw new Error('Email is not defined in integration')\n  }\n  await request({\n    baseUrl: url,\n    path: `/signout?value=${email}`,\n    method: 'GET',\n    token\n  })\n}\n\nexport async function disconnect (integration: Integration): Promise<void> {\n  const integrationClient = await getIntegrationClient()\n  const result = await integrationClient.removeIntegration(integration.socialId, integration.workspaceUuid)\n  if (result !== undefined && result.connectionRemoved) {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/calendar-resources/src/api.ts#L14-L50","documentation":"The calendar integration signout function needs the Calendar service URL and an auth token, both read from client metadata. If either metadata value is undefined the integration cannot call the calendar service, so it throws immediately.","triggerScenarios":"Calling signout (directly or via disconnect/disconnectAll) when calendar.metadata.CalendarServiceURL or presentation.metadata.Token metadata is not set — e.g. calendar service not deployed/configured or user session lacks a token.","commonSituations":"Self-hosted deployments where the CalendarServiceURL metadata was never configured; reverse proxy not exposing the calendar service; user signed in through a flow that does not populate the presentation Token; misconfigured frontend bootstrap.","solutions":["Configure calendar.metadata.CalendarServiceURL in the deployment metadata/branding setup","Ensure the user has a valid session so presentation.metadata.Token is set","Verify the calendar service is deployed and its URL is reachable before enabling the integration"],"exampleFix":"// before: metadata missing, error thrown\n// after: check before invoking integration\nconst url = getMetadata(calendar.metadata.CalendarServiceURL)\nconst token = getMetadata(presentation.metadata.Token)\nif (url === undefined || token === undefined) {\n  console.warn('Calendar integration unavailable: missing service URL or token')\n} else {\n  await signout(integration, client)\n}","handlingStrategy":"validation","validationCode":"const url = getMetadata(calendar.metadata.CalendarServiceURL)\nconst token = getMetadata(presentation.metadata.Token)\nif (url === undefined || token === undefined) return // skip signout, integration not configured","typeGuard":"const isCalendarConfigured = (): boolean =>\n  getMetadata(calendar.metadata.CalendarServiceURL) !== undefined &&\n  getMetadata(presentation.metadata.Token) !== undefined","tryCatchPattern":"try {\n  await signout(integration, client)\n} catch (err) {\n  if ((err as Error).message.includes('URL or token is not defined')) {\n    logger.warn('Calendar signout skipped: service not configured')\n  } else throw err\n}","preventionTips":["Set CalendarServiceURL in deployment metadata/branding before enabling calendar integration","Verify Token metadata is present in the auth bootstrap","Add a config preflight check listing required metadata at app startup"],"tags":["configuration","metadata","calendar"],"backgroundTag":"missing-env-var","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}