hcengineering/platform · error · Error

No token available

Error message

No token available

What it means

ExportButton reads the auth token from presentation metadata (`presentation.metadata.Token`). If it is null or undefined the export cannot authenticate against the export service, so 'No token available' is thrown before any fetch is made. It indicates the user's session/token was not injected into the client metadata.

Source

Thrown at plugins/export-resources/src/components/ExportButton.svelte:33

<script lang="ts">
  import { Class, Doc, Ref } from '@hcengineering/core'
  import { Button, showPopup } from '@hcengineering/ui'
  import { getMetadata } from '@hcengineering/platform'
  import presentation, { MessageBox } from '@hcengineering/presentation'
  import { type TransformConfig } from '@hcengineering/export'
  import plugin from '../plugin'

  export let _class: Ref<Class<Doc>>
  export let query: string = ''
  export let visible: boolean = false
  export let config: TransformConfig = {}

  async function handleExport (): Promise<void> {
    try {
      const baseUrl = getMetadata(plugin.metadata.ExportUrl)
      const token = getMetadata(presentation.metadata.Token)
      if (token == null) {
        throw new Error('No token available')
      }

      const res = await fetch(`${baseUrl}/exportSync?format=csv`, {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          _class,
          query,
          attributesOnly: true,
          config
        })
      })

      if (!res.ok) {
        showPopup(MessageBox, {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Ensure the user is logged in and the token metadata is set before rendering the export button.
  2. Check that the presentation/auth plugin providing metadata.Token is properly installed and initialized.
  3. Re-authenticate (refresh session) if the token was dropped after expiry, then retry the export.

Example fix

// before
const token = getMetadata(presentation.metadata.Token)
if (token == null) throw new Error('No token available')
// after
const token = getMetadata(presentation.metadata.Token)
if (token == null) {
  ui.notify('Please sign in again to export')
  void login()
  return
}
Defensive patterns

Strategy: type-guard

Validate before calling

const token = getMetadata(presentation.metadata.Token)
if (token == null || token === '') { ui.notify('Sign in to export'); return }

Type guard

function hasToken(t: string | null | undefined): t is string { return typeof t === 'string' && t.length > 0 }

Try / catch

try {
  await handleExport()
} catch (e) {
  if (e instanceof Error && e.message === 'No token available') {
    ui.notify('Your session has no auth token; please sign in again')
  } else throw e
}

Prevention

When it happens

Trigger: `getMetadata(presentation.metadata.Token)` returns null because the login/session flow did not provide a token, or the plugin metadata was not registered/initialized.

Common situations: Expired or missing session, running the component in a context without login metadata (tests, storybook, embedded preview), or misconfigured auth plugin registration.

Related errors


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