hcengineering/platform · error · Error

Message id is required

Error message

Message id is required

What it means

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).

Source

Thrown at foundations/communication/packages/shared/src/processor.ts:55

  PatchEvent,
  RemoveAttachmentsOperation,
  RemoveNotificationContextEvent,
  SetAttachmentsOperation,
  UpdateAttachmentsOperation,
  UpdateNotificationContextEvent,
  ReactionPatchEvent,
  AttachmentPatchEvent,
  BlobPatchEvent,
  ThreadPatchEvent
} from '@hcengineering/communication-sdk-types'

import { withTotal } from './utils'

// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class MessageProcessor {
  static create (event: CreateMessageEvent, id?: MessageID): Message {
    const messageId = event.messageId ?? (id as MessageID)
    if (messageId == null) throw new Error('Message id is required')
    return {
      id: messageId,
      cardId: event.cardId,
      type: event.messageType,
      content: event.content,
      extra: event.extra,
      creator: event.socialId,
      created: new Date(event.date ?? Date.now()),
      language: event.language,
      reactions: {},
      attachments: [],
      threads: []
    }
  }

  static applyPatch (message: Message, patchEvent: PatchEvent): Message | undefined {
    return applyPatchEvent(message, patchEvent)
  }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Pass the id explicitly as the second argument: MessageProcessor.create(event, generatedId).
  2. Assign event.messageId before calling create, or generate one with a UUID when absent.
  3. 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).
  4. Add messageId to test fixtures/producers so events always carry an id.

Example fix

// before
const message = MessageProcessor.create({ cardId, content } as CreateMessageEvent)
// Error: Message id is required
// after
const message = MessageProcessor.create({ cardId, content, messageId: crypto.randomUUID() } as CreateMessageEvent)
Defensive patterns

Strategy: type-guard

Validate before calling

function assertEventHasId(event: CreateMessageEvent, id?: MessageID): MessageID {
  const mid = event.messageId ?? id
  if (mid == null) throw new Error('Provide event.messageId or an explicit id to MessageProcessor.create')
  return mid
}

Type guard

function hasId(event: CreateMessageEvent, id?: MessageID): event is CreateMessageEvent & { messageId: MessageID } {
  return (event.messageId ?? id) != null
}

Try / catch

try {
  const message = MessageProcessor.create(event, id)
} catch (e) {
  if (e.message === 'Message id is required') {
    return MessageProcessor.create({ ...event, messageId: crypto.randomUUID() }, id)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling MessageProcessor.create(event) where event.messageId is null/undefined and the second `id` argument is omitted or also undefined.

Common situations: 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.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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