{"record":{"id":"ac60c3885258ac76","repo":"hcengineering/platform","slug":"event-or-workspace-or-type-is-missing","errorCode":null,"errorMessage":"'event' or 'workspace' or 'type' is missing","messagePattern":"'event' or 'workspace' or 'type' is missing","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"services/calendar/pod-calendar/src/main.ts","lineNumber":173,"sourceCode":"\n        res.send()\n      }\n    },\n    {\n      endpoint: '/event',\n      type: 'post',\n      handler: async (req, res) => {\n        const token = extractToken(req.headers)\n\n        if (token === undefined) {\n          res.status(401).send()\n          return\n        }\n\n        const { event, workspace, type } = req.body\n\n        if (event === undefined || workspace === undefined || type === undefined) {\n          res.status(400).send({ err: \"'event' or 'workspace' or 'type' is missing\" })\n          return\n        }\n        void OutcomingClient.push(ctx, accountClient, workspace, event, type).catch((err: any) => {\n          ctx.error('Outcoming sync failed', { eventId: event.eventId, workspace, type, error: err.message })\n        })\n        res.send()\n      }\n    }\n  ]\n\n  const server = listen(createServer(endpoints), config.Port)\n\n  const shutdown = (): void => {\n    server.close(() => {\n      watchController.stop()\n      process.exit()\n    })\n  }","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/calendar/pod-calendar/src/main.ts#L155-L191","documentation":"The calendar outcoming-sync HTTP endpoint validates that the request body contains 'event', 'workspace' and 'type' fields before forwarding the event to the account outcoming client. If any of the three is undefined, the handler short-circuits with HTTP 400 and this message. It is a guard against malformed client payloads, not a server fault.","triggerScenarios":"POSTing to the calendar sync endpoint with a body missing req.body.event (the event object), req.body.workspace (the workspace UUID) or req.body.type (the sync type); e.g. sending { event, type } without workspace, or an empty body.","commonSituations":"Client SDKs or scripts calling the internal sync route by hand; JSON bodies where a field is serialized as null/omitted after upstream refactors renamed it; content-type not set to application/json so req.body is empty.","solutions":["Include all three fields in the JSON body: event (object with eventId), workspace (workspace UUID string) and type.","Ensure the request has Content-Type: application/json and an express json body parser is applied so req.body is populated.","Check the caller for renamed fields after an API update and align with the handler destructuring in main.ts."],"exampleFix":"// before\nawait fetch(url, { method: 'POST', body: JSON.stringify({ event, type }) })\n// after\nawait fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ event, workspace, type }) })","handlingStrategy":"validation","validationCode":"if (event === undefined || workspace === undefined || type === undefined) {\n  throw new Error('event, workspace and type are required before calling the sync endpoint')\n}","typeGuard":"function isSyncBody(b: unknown): b is { event: { eventId: string }, workspace: string, type: string } {\n  const o = b as any\n  return !!o && o.event !== undefined && typeof o.event.eventId === 'string' && typeof o.workspace === 'string' && typeof o.type === 'string'\n}","tryCatchPattern":"const res = await fetch(url, opts)\nif (res.status === 400) {\n  const body = await res.json()\n  throw new Error(`sync rejected: ${body.err}`)\n}","preventionTips":["Build the request body from a typed object so missing fields fail at compile time.","Always send Content-Type: application/json.","Validate required fields client-side before dispatching the sync request."],"tags":["http","validation","bad-request","calendar"],"backgroundTag":"missing-request-body-field","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}