hcengineering/platform · warning · ApiError

Missing required parameters

Error message

Missing required parameters

What it means

The export endpoint destructures req.body expecting a _class field identifying the document class to export. When req.body._class is null/undefined it throws this 400 immediately, before any authz or export work. The _class is mandatory because WorkspaceExporter needs to know what to export.

Source

Thrown at services/export/pod-export/src/server.ts:306

  app.use(express.json())

  app.post(
    '/exportAsync',
    wrapRequest(async (req, res, wsIds, token, socialId) => {
      const format = parseExportFormat(req.query.format)

      const {
        _class,
        query,
        attributesOnly
      }: {
        _class: Ref<Class<Doc<Space>>>
        query?: DocumentQuery<Doc>
        attributesOnly: boolean
      } = req.body

      if (_class == null) {
        throw new ApiError(400, 'Missing required parameters')
      }

      const decodedToken = decodeToken(token)
      if (decodedToken.extra?.readonly !== undefined) {
        throw new ApiError(403, 'Forbidden')
      }
      const isAdmin: boolean = decodedToken.extra?.admin === 'true'

      const accountClient = getClient(envConfig.AccountsUrl, token)

      try {
        const info = await accountClient.getLoginWithWorkspaceInfo()
        const winfo = info.workspaces[decodedToken.workspace]
        if (!isAdmin) {
          if (winfo === undefined) {
            res.status(401).end('Invalid workspace')
            return
          } else {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Include _class in the request body, e.g. { _class: 'contact:Person', format: 'json' }.
  2. Set Content-Type: application/json on the request so express parses the body.
  3. Log req.body client-side/server-side to confirm what the server actually received.

Example fix

// before
await fetch('/export', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ format: 'csv' }) })
// after
await fetch('/export', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ _class: 'contact:Person', format: 'csv' }) })
Defensive patterns

Strategy: validation

Validate before calling

if (body._class == null || typeof body._class !== 'string') {
  throw new Error('export requires a string _class, e.g. contact:Person')
}

Type guard

function hasRequiredExportBody(b: unknown): b is { _class: string } {
  return typeof b === 'object' && b !== null && typeof (b as any)._class === 'string'
}

Try / catch

try {
  const res = await fetch('/export', { ... })
  const err = await res.json()
  if (res.status === 400 && err.message === 'Missing required parameters') {
    console.error('Request body missing _class — payload sent:', JSON.stringify(body))
  }
} catch (e) { /* handle */ }

Prevention

When it happens

Trigger: POST to the export route with a JSON body lacking _class, e.g. { format: 'csv', query: {...} } or sending an empty body / wrong Content-Type so body parses without _class.

Common situations: Forgetting Content-Type: application/json so the body middleware leaves req.body empty; renaming the field client-side (class, className); copy-pasting a curl example without _class.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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