ellite/Wallos · error · Exception

$this->lang('file_access') . $path

Error message

$this->lang('file_access') . $path

What it means

addAttachment() throws lang('file_access') followed by the path when static::fileIsAccessible() reports the file cannot be read (missing file or unreadable permissions). The exception severity is STOP_CONTINUE, so with exceptions disabled PHPMailer records the error and continues; with exceptions enabled it propagates.

Solutions

  1. Verify the file exists and is readable with is_file() and is_readable() before addAttachment()
  2. Use absolute paths (e.g. __DIR__ . '/files/report.pdf') instead of relative ones
  3. Fix filesystem permissions so the web-server/PHP user can read the file
  4. Check isError()/errorInfo() after addAttachment if you run with exceptions disabled

Example fix

// before
$mail->addAttachment('uploads/report.pdf');
// after
$path = __DIR__ . '/uploads/report.pdf';
if (!is_file($path) || !is_readable($path)) { throw new RuntimeException("Attachment not readable: $path"); }
$mail->addAttachment($path, 'report.pdf');
Defensive patterns

Strategy: validation

Validate before calling

$path = __DIR__ . '/uploads/report.pdf';
if (!is_file($path) || !is_readable($path)) { throw new RuntimeException("Attachment missing or unreadable: $path"); }
$mail->addAttachment($path, 'report.pdf');

Type guard

function readableFilePath($p): ?string { return is_string($p) && is_file($p) && is_readable($p) ? $p : null; }

Try / catch

try { $ok = $mail->addAttachment($path); if (!$ok) throw new RuntimeException($mail->ErrorInfo); } catch (PHPMailer\PHPMailer\Exception $e) { error_log('Attachment failed: ' . $e->getMessage()); }

Prevention

When it happens

Trigger: Calling $mail->addAttachment('/path/to/file.pdf') where the file does not exist, is a directory, or the PHP process lacks read permission.

Common situations: Relative paths resolved against the CWD instead of the script directory, files uploaded then moved/deleted before send(), wrong permissions after deployment, or path typos in config.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13). Data as JSON: /api/errors/611f994e9461b35f. Report an issue: GitHub.

Appendix: source

Thrown at libs/PHPMailer/PHPMailer.php:3228

     * @param string $name        Overrides the attachment name
     * @param string $encoding    File encoding (see $Encoding)
     * @param string $type        MIME type, e.g. `image/jpeg`; determined automatically from $path if not specified
     * @param string $disposition Disposition to use
     *
     * @throws Exception
     *
     * @return bool
     */
    public function addAttachment(
        $path,
        $name = '',
        $encoding = self::ENCODING_BASE64,
        $type = '',
        $disposition = 'attachment'
    ) {
        try {
            if (!static::fileIsAccessible($path)) {
                throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
            }

            //If a MIME type is not specified, try to work it out from the file name
            if ('' === $type) {
                $type = static::filenameToType($path);
            }

            $filename = (string) static::mb_pathinfo($path, PATHINFO_BASENAME);
            if ('' === $name) {
                $name = $filename;
            }
            if (!$this->validateEncoding($encoding)) {
                throw new Exception($this->lang('encoding') . $encoding);
            }

            $this->attachment[] = [
                0 => $path,
                1 => $filename,

View on GitHub (pinned to 52820e87ca)