instructure/canvas-lms · warning · ConversationsHelper::RepliesLockedForUser
Unauthorized, unable to add messages to conversation
Error message
Unauthorized, unable to add messages to conversation
What it means
process_response in ConversationsHelper validates that the current user may add a message to the conversation. ConversationsHelper::RepliesLockedForUser (a subclass of Error) is raised with status :unauthorized when replies are locked for the user for the given recipients, preventing automated/manual message adds to a locked conversation.
Solutions
- Check replies_locked_for? before attempting to add the message and skip gracefully
- Verify the current_user is an active participant of the conversation
- If automation (e.g. out-of-office responses), rescue ConversationsHelper::RepliesLockedForUser and log instead of failing the job
- Restore the user's participation or use a conversation that is not locked
Example fix
// before add_message(conversation, ...) // after unless conversation.conversation.replies_locked_for?(current_user, recipients) add_message(conversation, ...) end
Defensive patterns
Strategy: try-catch
Validate before calling
locked = conversation.conversation.replies_locked_for?(current_user, recipients)
render json: { errors: ['replies locked'] }, status: :unauthorized if locked Try / catch
begin
process_response(...)
rescue ConversationsHelper::RepliesLockedForUser => e
render json: { error: e.message }, status: :unauthorized
end Prevention
- Check replies_locked_for? before attempting sends
- In background jobs, rescue and log instead of crashing
- Verify user participation before composing replies
When it happens
Trigger: Calling process_response (directly or via trigger_out_of_office_auto_responses) on a conversation whose conversation#replies_locked_for?(current_user, recipients) is true — e.g. the conversation was locked/retired or the user lost participation rights.
Common situations: Automated out-of-office reply jobs firing for conversations where the user can no longer reply; a user replying in the UI after an admin locked the thread; sending messages to a conversation after being removed as a participant.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- can only forward one conversation at a time
- can't add participants if there are no messages
- can't add participants to a private conversation
- Course concluded, unable to send messages
- user doesn't have permission to forward these messages
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/01064406979c97e0.
Report an issue: GitHub.
Appendix: source
Thrown at app/helpers/conversations_helper.rb:37
module ConversationsHelper
def process_response(
conversation:,
context:,
current_user:,
session:,
recipients:,
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:
)
View on GitHub (pinned to 1c9f0bb801)