{"record":{"id":"13715ce147faf193","repo":"instructure/canvas-lms","slug":"could-not-send-slack-message-without-configured-key","errorCode":null,"errorMessage":"Could not send slack message without configured key","messagePattern":"Could not send slack message without configured key","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app/models/message.rb","lineNumber":735,"sourceCode":"\n    @i18n_scope = nil\n  end\n  # rubocop:enable Security/Eval\n\n  # Public: Deliver this message.\n  #\n  # Returns nothing.\n  def deliver\n    # don't dispatch canceled or already-sent messages.\n    return nil unless dispatch\n\n    unless path_type.present?\n      logger.warn \"Could not find a path type for #{inspect}\"\n      return nil\n    end\n\n    if path_type == \"slack\" && !context_root_account.settings[:encrypted_slack_key]\n      logger.warn(\"Could not send slack message without configured key\")\n      return nil\n    end\n\n    check_acct = infer_feature_account\n\n    return skip_and_cancel if path_type == \"sms\"\n\n    if path_type == \"push\" &&\n       (Notification.types_to_send_in_push.exclude?(notification_name) || !check_acct.enable_push_notifications?)\n      return skip_and_cancel\n    end\n\n    InstStatsd::Statsd.distributed_increment(\"message.deliver.#{path_type}.#{notification_name}\",\n                                             short_stat: \"message.deliver\",\n                                             tags: { path_type:, notification_name: })\n\n    global_account_id = Shard.global_id_for(root_account_id, shard)\n    InstStatsd::Statsd.increment(\"message.deliver.#{path_type}.#{global_account_id}\",","sourceCodeStart":717,"sourceCodeEnd":753,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/message.rb#L717-L753","documentation":"Message#deliver determines the path_type (email, sms, slack, ...). For slack messages, the root account must have an encrypted_slack_key in its settings; if absent, it logs this warning and returns nil, so the notification is silently never sent. It is a guard against dispatching Slack messages with no configured credential.","triggerScenarios":"A notification policy routes a message to a Slack path while context_root_account.settings[:encrypted_slack_key] is unset — Slack notification type enabled without completing Slack integration setup on the account.","commonSituations":"Admin turned on Slack notifications but skipped key configuration; account settings cloned/exported without the encrypted key; multi-tenant setups where only some accounts have Slack configured; keys removed during secret rotation.","solutions":["Configure the Slack integration on the root account so settings[:encrypted_slack_key] is set (complete the Slack app setup in account settings)","If Slack should not be used, remove/disable the Slack contact-channel/notification policy for affected users","Check which account the message's context resolves to — the key must exist on that root account, not just the default","Re-queue/resend the affected notification after configuring the key"],"exampleFix":"// before\n# account.settings has no :encrypted_slack_key; message dropped\n// after\nacct.settings[:encrypted_slack_key] = Canvas::Security.encrypt_text(slack_signing_secret)\nacct.save!","handlingStrategy":"validation","validationCode":"def slack_configured?(message)\n  message.context_root_account.settings[:encrypted_slack_key].present?\nend\n# gate Slack notification policies on this check","typeGuard":null,"tryCatchPattern":"begin\n  message.deliver\nrescue => e\n  Canvas::Errors.capture(e, message_id: message.id)\nend","preventionTips":["Complete Slack integration setup (encrypted key) on the root account before enabling Slack notifications","Audit account settings after clones/exports to ensure :encrypted_slack_key survived","Verify the message's context resolves to an account that has Slack configured","Re-send dropped notifications after configuring the key"],"tags":["notifications","slack","configuration","messages"],"backgroundTag":"missing-config-key","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}