instructure/canvas-lms · error · ConversationsHelper::Error

Unable to create message without a body

Error message

Unable to create message without a body

What it means

process_response requires a non-blank message body before creating the message; a blank body raises ConversationsHelper::Error with status :bad_request and attribute 'empty_message'. This prevents empty conversation entries from being created.

Solutions

  1. Ensure body is non-blank before calling — validate on the client and server
  2. Rescue ConversationsHelper::Error with status :bad_request and re-prompt the user for content
  3. If automation, guard: skip sending when the generated body is blank
  4. Trim/normalize the body and fall back to a sensible default text if appropriate

Example fix

// before
add_message(conversation, body: nil, ...)
// after
add_message(conversation, body: body.presence || 'No message content provided', ...)
Defensive patterns

Strategy: validation

Validate before calling

return render json: { error: 'body required' }, status: :bad_request if body.blank?

Try / catch

begin
  process_response(...)
rescue ConversationsHelper::Error => e
  if e.message.include?('without a body')
    render json: { error: 'message body required' }, status: :bad_request
  else
    raise
  end
end

Prevention

When it happens

Trigger: Calling process_response (directly or via trigger_out_of_office_auto_responses) with body set to nil, "", or whitespace-only text.

Common situations: A client submitting an empty composer; an automation assembling a message from a template that rendered empty; stripped HTML leaving nothing after sanitization.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/ffd8a3bbddd3ecbe. Report an issue: GitHub.

Appendix: source

Thrown at app/helpers/conversations_helper.rb:45

    context_code:,
    message_ids:,
    body:,
    attachment_ids:,
    domain_root_account_id:,
    media_comment_id:,
    media_comment_type:,
    automated: false
  )
    if conversation.conversation.replies_locked_for?(current_user, recipients)
      raise ConversationsHelper::RepliesLockedForUser.new(message: I18n.t("Unauthorized, unable to add messages to conversation"), status: :unauthorized, attribute: "workflow_state")
    end

    if context.is_a?(Course) && context.workflow_state == "completed" && !context.grants_right?(current_user, session, :read_as_admin)
      raise ConversationsHelper::Error.new(message: I18n.t("Course concluded, unable to send messages"), status: :unauthorized, attribute: "workflow_state")
    end

    if body.blank?
      raise ConversationsHelper::Error.new(message: I18n.t("Unable to create message without a body"), status: :bad_request, attribute: "empty_message")
    end

    recipients = normalize_recipients(
      recipients:,
      context_code:,
      conversation_id: conversation.conversation_id,
      current_user:,
      session:
    )

    if recipients && !conversation.conversation.can_add_participants?(recipients)
      raise ConversationsHelper::Error.new(message: I18n.t("Too many participants for group conversation"), status: :bad_request, attribute: "recipients")
    end

    invalid_recipients = get_invalid_recipients(context, recipients, current_user)
    unless invalid_recipients.to_a.empty?
      invalid_recipients = invalid_recipients.pluck(1)
      raise ConversationsHelper::Error.new(message: I18n.t("The following recipients have no active enrollment in the course, %{invalid_recipients}, unable to send messages", invalid_recipients:), status: :unauthorized, attribute: "recipients")

View on GitHub (pinned to 1c9f0bb801)