{"record":{"id":"ec5fea647b8071e6","repo":"django/django","slug":"could-not-create-file-path-self-file-path-e","errorCode":null,"errorMessage":"Could not create 'file_path': {self.file_path} ({err})","messagePattern":"Could not create 'file_path': (.+?) \\((.+?)\\)","errorType":"exception","errorClass":"InvalidMailer","httpStatus":null,"severity":"error","filePath":"django/core/mail/backends/filebased.py","lineNumber":63,"sourceCode":"            # Make sure that self.file_path is writable.\n            if not os.access(self.file_path, os.W_OK):\n                raise ImproperlyConfigured(\n                    \"Could not write to directory: %s\" % self.file_path\n                )\n            return\n\n        if file_path is None:\n            raise InvalidMailer(\"OPTIONS must define 'file_path'.\", alias=self.alias)\n        self.file_path = os.path.abspath(file_path)\n        try:\n            os.makedirs(self.file_path, exist_ok=True)\n        except FileExistsError:\n            raise InvalidMailer(\n                f\"'file_path' is not a directory: {self.file_path}\",\n                alias=self.alias,\n            )\n        except OSError as err:\n            raise InvalidMailer(\n                f\"Could not create 'file_path': {self.file_path} ({err})\",\n                alias=self.alias,\n            )\n        if not os.access(self.file_path, os.W_OK):\n            raise InvalidMailer(\n                f\"'file_path' is not writable: {self.file_path}\",\n                alias=self.alias,\n            )\n\n    def write_message(self, message):\n        self.stream.write(message.message().as_bytes() + b\"\\n\")\n        self.stream.write(b\"-\" * 79)\n        self.stream.write(b\"\\n\")\n\n    def _get_filename(self):\n        \"\"\"Return a unique file name.\"\"\"\n        if self._fname is None:\n            timestamp = datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/django/django/blob/b5388a3a80cafcce2e34196d8e81cf5b48eb33bb/django/core/mail/backends/filebased.py#L45-L81","documentation":"The file-based email backend raises this InvalidMailer when os.makedirs(self.file_path, exist_ok=True) fails with an OSError other than FileExistsError — most commonly permission denied, read-only filesystem, or disk full. It indicates the directory at file_path could not be created for an OS-level reason, reported verbatim in the message. This is the MAILERS-enabled code path (alias is not None).","triggerScenarios":"A MAILERS entry using the filebased backend whose OPTIONS 'file_path' points to a location the current process cannot create directories under, e.g. '/root/mail' run as a non-root user, a read-only mount, or a parent directory that does not exist and cannot be auto-created due to permissions. The exception is raised at backend instantiation (when mail.mailers[alias] is first accessed).","commonSituations":"Running the Django process under a different user than the one owning the target directory; deploying to a read-only filesystem (e.g. some container images) without mounting a writable volume; specifying a relative file_path that resolves to an unexpected absolute location; the parent directory was removed between deploys.","solutions":["Check the (err) portion of the message for the OS-level cause (PermissionError, OSError, etc.) and resolve that first.","Ensure the parent directory of file_path exists and is writable by the Django process user (mkdir -p and chown).","Point file_path to a location on a writable, persistent volume, especially in containerized deployments.","Run the web/worker process under a user that has write access to the configured file_path."],"exampleFix":"// before\nMAILERS = {\n    \"default\": {\n        \"OPTIONS\": {\"file_path\": \"/srv/readonly/emails\"}\n    }\n}\n// after\nMAILERS = {\n    \"default\": {\n        \"OPTIONS\": {\"file_path\": \"/var/lib/django/emails\"}\n    }\n}\n# plus: chown -R appuser:appuser /var/lib/django/emails","handlingStrategy":"validation","validationCode":"import os, tempfile\ndef ensure_writable_parent(path):\n    parent = os.path.dirname(os.path.abspath(path))\n    if not os.path.isdir(parent):\n        try:\n            os.makedirs(parent, exist_ok=True)\n        except OSError as e:\n            raise ImproperlyConfigured(f\"Cannot create parent dir for {path}: {e}\")\n    if not os.access(parent, os.W_OK):\n        raise ImproperlyConfigured(f\"Parent not writable: {parent}\")\n    return path","typeGuard":null,"tryCatchPattern":"from django.core.mail import InvalidMailer\ntry:\n    conn = mail.mailers['default']\nexcept InvalidMailer as e:\n    log.error('Mailer misconfigured: %s', e)\n    # fall back to console backend or alert ops","preventionTips":["Run the Django process under a user that owns the email output directory.","Mount a writable volume for file_path in containers.","Add a system check that attempts makedirs on file_path at startup.","Document required directory permissions alongside the MAILERS config."],"tags":["email","file-based","configuration","mailers","permissions","filesystem"],"backgroundTag":null,"analyzedSha":"b5388a3a80cafcce2e34196d8e81cf5b48eb33bb","analyzedAt":"2026-08-10T17:37:52.993Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}