{"record":{"id":"55709c6e54f52900","repo":"hcengineering/platform","slug":"message-id-is-required-55709c","errorCode":null,"errorMessage":"Message id is required","messagePattern":"Message id is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"foundations/communication/packages/shared/src/processor.ts","lineNumber":55,"sourceCode":"  PatchEvent,\n  RemoveAttachmentsOperation,\n  RemoveNotificationContextEvent,\n  SetAttachmentsOperation,\n  UpdateAttachmentsOperation,\n  UpdateNotificationContextEvent,\n  ReactionPatchEvent,\n  AttachmentPatchEvent,\n  BlobPatchEvent,\n  ThreadPatchEvent\n} from '@hcengineering/communication-sdk-types'\n\nimport { withTotal } from './utils'\n\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class MessageProcessor {\n  static create (event: CreateMessageEvent, id?: MessageID): Message {\n    const messageId = event.messageId ?? (id as MessageID)\n    if (messageId == null) throw new Error('Message id is required')\n    return {\n      id: messageId,\n      cardId: event.cardId,\n      type: event.messageType,\n      content: event.content,\n      extra: event.extra,\n      creator: event.socialId,\n      created: new Date(event.date ?? Date.now()),\n      language: event.language,\n      reactions: {},\n      attachments: [],\n      threads: []\n    }\n  }\n\n  static applyPatch (message: Message, patchEvent: PatchEvent): Message | undefined {\n    return applyPatchEvent(message, patchEvent)\n  }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/communication/packages/shared/src/processor.ts#L37-L73","documentation":"MessageProcessor.create builds a Message domain object from a CreateMessageEvent, resolving the id from event.messageId or an optional explicit id parameter. If neither yields a value, it throws 'Message id is required'. This is the shared factory-level guard mirrored by the server's storage middleware (error 26).","triggerScenarios":"Calling MessageProcessor.create(event) where event.messageId is null/undefined and the second `id` argument is omitted or also undefined.","commonSituations":"Building messages in client/shared code from incoming events that never had ids assigned; passing an id variable typed MessageID but actually undefined at runtime (TS cast `(id as MessageID)` hides the null); test fixtures missing messageId.","solutions":["Pass the id explicitly as the second argument: MessageProcessor.create(event, generatedId).","Assign event.messageId before calling create, or generate one with a UUID when absent.","Fix the misleading cast `(id as MessageID)` — make the parameter `id?: MessageID` checked properly (it already is null-checked, but avoid casting undefined values at call sites).","Add messageId to test fixtures/producers so events always carry an id."],"exampleFix":"// before\nconst message = MessageProcessor.create({ cardId, content } as CreateMessageEvent)\n// Error: Message id is required\n// after\nconst message = MessageProcessor.create({ cardId, content, messageId: crypto.randomUUID() } as CreateMessageEvent)","handlingStrategy":"type-guard","validationCode":"function assertEventHasId(event: CreateMessageEvent, id?: MessageID): MessageID {\n  const mid = event.messageId ?? id\n  if (mid == null) throw new Error('Provide event.messageId or an explicit id to MessageProcessor.create')\n  return mid\n}","typeGuard":"function hasId(event: CreateMessageEvent, id?: MessageID): event is CreateMessageEvent & { messageId: MessageID } {\n  return (event.messageId ?? id) != null\n}","tryCatchPattern":"try {\n  const message = MessageProcessor.create(event, id)\n} catch (e) {\n  if (e.message === 'Message id is required') {\n    return MessageProcessor.create({ ...event, messageId: crypto.randomUUID() }, id)\n  }\n  throw e\n}","preventionTips":["Generate messageId at event creation; never rely on the optional second id argument being set.","Avoid `as MessageID` casts of possibly-undefined values — they hide null at compile time.","Add messageId to test fixtures and event builders by default.","Validate events at the boundary before invoking shared processors."],"tags":["validation","typescript","messages","factory"],"backgroundTag":"missing-required-field","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}