hcengineering/platform · error · TokenError

Invalid grant workspace uuid: "${grant?.workspace}"

Error message

Invalid grant workspace uuid: "${grant?.workspace}"

What it means

When options.grant.workspace is set, generateToken validates it is a real UUID before embedding it into the token's grant. This prevents signing tokens whose workspace grant references a malformed id.

Source

Thrown at foundations/core/packages/token/src/token.ts:75

  workspaceUuid?: WorkspaceUuid,
  extra?: Record<string, string>,
  secret?: string,
  options?: {
    grant?: PermissionsGrant
    nbf?: number
    exp?: number
    sub?: PersonUuid
  }
): string {
  if (!validate(accountUuid)) {
    throw new TokenError(`Invalid account uuid: "${accountUuid}"`)
  }
  if (workspaceUuid !== undefined && !validate(workspaceUuid)) {
    throw new TokenError(`Invalid workspace uuid: "${workspaceUuid}"`)
  }
  const { grant, nbf, exp, sub } = options ?? {}
  if (grant?.workspace !== undefined && !validate(grant?.workspace)) {
    throw new TokenError(`Invalid grant workspace uuid: "${grant?.workspace}"`)
  }

  if (grant != null && sub == null && (nbf == null || exp == null)) {
    throw new TokenError('nbf and exp are required when sub is not provided')
  }

  const service = getMetadata(serverPlugin.metadata.Service)
  if (service !== undefined) {
    extra = { service, ...extra }
  }

  const sanitizedGrant: PermissionsGrant | undefined =
    grant !== undefined
      ? {
          workspace: grant.workspace,
          role: grant.role,
          grantedBy: grant.grantedBy,
          firstName: grant.firstName,

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Validate grant.workspace with a UUID validator before building the options object
  2. Omit the workspace property entirely if there is no valid workspace grant
  3. Fix the upstream lookup that produced the bad workspace id

Example fix

// before
const grant = { workspace: row.ws_id }
// after
const grant = validate(row.ws_id) ? { workspace: row.ws_id } : undefined
Defensive patterns

Strategy: validation

Validate before calling

const grant = grantWorkspace !== undefined
  ? (isUuid(grantWorkspace) ? { workspace: grantWorkspace } : undefined)
  : undefined
if (grantWorkspace !== undefined && grant === undefined) {
  throw new Error(`grant.workspace "${grantWorkspace}" is not a valid UUID`)
}

Type guard

function isValidGrant(g: unknown): g is { workspace: string } {
  return typeof g === 'object' && g !== null && 'workspace' in g && isUuid((g as any).workspace)
}

Try / catch

try {
  const token = generateToken(accountUuid, workspaceUuid, { grant })
} catch (e) {
  if (e instanceof TokenError && e.message.includes('Invalid grant workspace uuid')) {
    throw new ConfigError(`grant.workspace "${grant?.workspace}" is malformed`)
  }
  throw e
}

Prevention

When it happens

Trigger: Passing grant: { workspace: '...' } with a workspace id that is undefined-ish, empty, or not a valid UUID (note the check only runs when the property is present).

Common situations: Constructing grants programmatically where the workspace id comes from a lookup that failed and returned a partial string; JSON config with placeholder values.

Related errors


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