instructure/canvas-lms · error
Folder # does not exist.
Error message
Folder #{folder} does not exist. What it means
DirectoryMailbox#connect validates the configured incoming-mail directory before processing. If folder_exists?(folder) is false — the path configured as the mailbox does not exist on disk — connect raises immediately so the mail poller fails fast instead of silently processing nothing.
Solutions
- Create the configured folder: mkdir -p <configured folder path>.
- Verify the :folder option in the incoming mail / canvas.yml settings matches an existing absolute path.
- In containerized deployments, confirm the mail spool volume is mounted at the configured path.
- Fix environment-specific config (staging vs production) so the directory exists where the process runs.
Example fix
// before (config) incoming_mail: mailbox: directory folder: /var/mail/canvas_inbound # does not exist // after # on host/container: mkdir -p /var/mail/canvas_inbound incoming_mail: mailbox: directory folder: /var/mail/canvas_inbound # exists and writable by app user
Defensive patterns
Strategy: validation
Validate before calling
folder = config[:folder]
raise "mailbox folder missing: #{folder}" unless File.directory?(folder) Try / catch
begin mailbox.connect rescue RuntimeError => e raise unless e.message =~ /Folder .* does not exist/ FileUtils.mkdir_p(config[:folder]) retry end
Prevention
- Provision the mail spool directory in deployment manifests (Dockerfile/entrypoint).
- Use absolute paths and verify mounts in containerized environments.
- Add a startup health check that fails early if the configured folder is absent.
When it happens
Trigger: Starting IncomingMessageProcessor with a directory mailbox whose :folder option points to a non-existent path; directory removed/renamed after config was written; wrong mount point or volume not mounted when running in a container.
Common situations: Typo or wrong absolute path in incoming mail settings; Docker/Kubernetes volume not mounted; permissions or deploy changed wiping the mail spool directory; staging config pointing at a host path that doesn't exist in the new environment.
Related errors
- unrecognized setting sent to IncomingMessageProcessor: #
- A partner ID is required to use Academic Benchmarks
- A partner key is required to use Academic Benchmarks
- an object with an interface for loading settings must be…
- an object with an interface for loading settings must be…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/78744f0a050bd7f2.
Report an issue: GitHub.
Appendix: source
Thrown at gems/incoming_mail_processor/lib/incoming_mail_processor/directory_mailbox.rb:40
require "zlib"
require_relative "configurable_timeout"
module IncomingMailProcessor
class DirectoryMailbox
include ConfigurableTimeout
attr_accessor :folder
def initialize(options = {})
@folder = options.fetch(:folder, "")
@options = options
wrap_with_timeout(self,
%i[folder_exists? files_in_folder read_file file? delete_file move_file create_folder])
end
def connect
raise "Folder #{folder} does not exist." unless folder_exists?(folder)
end
def disconnect
# nothing to do
end
def each_message(opts = {})
filenames = files_in_folder(folder)
filenames = filenames.select { |filename| Zlib.crc32(filename) % opts[:stride] == opts[:offset] } if opts[:stride] && opts[:offset]
filenames.each do |filename|
if file?(folder, filename)
body = read_file(folder, filename)
yield filename, body
end
end
end
def delete_message(filename)View on GitHub (pinned to 1c9f0bb801)