{"record":{"id":"0bc34f24f378dae0","repo":"hcengineering/platform","slug":"missing-required-parameters","errorCode":null,"errorMessage":"Missing required parameters","messagePattern":"Missing required parameters","errorType":"http","errorClass":"ApiError","httpStatus":400,"severity":"warning","filePath":"services/export/pod-export/src/server.ts","lineNumber":306,"sourceCode":"  app.use(express.json())\n\n  app.post(\n    '/exportAsync',\n    wrapRequest(async (req, res, wsIds, token, socialId) => {\n      const format = parseExportFormat(req.query.format)\n\n      const {\n        _class,\n        query,\n        attributesOnly\n      }: {\n        _class: Ref<Class<Doc<Space>>>\n        query?: DocumentQuery<Doc>\n        attributesOnly: boolean\n      } = req.body\n\n      if (_class == null) {\n        throw new ApiError(400, 'Missing required parameters')\n      }\n\n      const decodedToken = decodeToken(token)\n      if (decodedToken.extra?.readonly !== undefined) {\n        throw new ApiError(403, 'Forbidden')\n      }\n      const isAdmin: boolean = decodedToken.extra?.admin === 'true'\n\n      const accountClient = getClient(envConfig.AccountsUrl, token)\n\n      try {\n        const info = await accountClient.getLoginWithWorkspaceInfo()\n        const winfo = info.workspaces[decodedToken.workspace]\n        if (!isAdmin) {\n          if (winfo === undefined) {\n            res.status(401).end('Invalid workspace')\n            return\n          } else {","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/export/pod-export/src/server.ts#L288-L324","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Include _class in the request body, e.g. { _class: 'contact:Person', format: 'json' }.","Set Content-Type: application/json on the request so express parses the body.","Log req.body client-side/server-side to confirm what the server actually received."],"exampleFix":"// before\nawait fetch('/export', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ format: 'csv' }) })\n// after\nawait fetch('/export', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ _class: 'contact:Person', format: 'csv' }) })","handlingStrategy":"validation","validationCode":"if (body._class == null || typeof body._class !== 'string') {\n  throw new Error('export requires a string _class, e.g. contact:Person')\n}","typeGuard":"function hasRequiredExportBody(b: unknown): b is { _class: string } {\n  return typeof b === 'object' && b !== null && typeof (b as any)._class === 'string'\n}","tryCatchPattern":"try {\n  const res = await fetch('/export', { ... })\n  const err = await res.json()\n  if (res.status === 400 && err.message === 'Missing required parameters') {\n    console.error('Request body missing _class — payload sent:', JSON.stringify(body))\n  }\n} catch (e) { /* handle */ }","preventionTips":["Always send Content-Type: application/json so the body parses.","Build request payloads from a typed helper that requires _class at compile time.","Log the outgoing body in tests before shipping integrations."],"tags":["validation","http-400","missing-parameter","request-body"],"backgroundTag":"missing-required-parameter","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}