sebastianbergmann/php-text-template · error · InvalidArgumentException

Failed to load template "%s"

Error message

Failed to load template "%s"

What it means

Template's constructor loads the template file immediately via loadTemplateFile(). The loader first tries the given path; if it is not a readable file (or reads as empty), it retries with a '.dist' suffix appended (e.g. config/config.dist). If neither file yields a non-empty string, an InvalidArgumentException naming the original path is thrown. Since the property is readonly, a failed construction cannot be retried on the same instance.

Solutions

  1. Check the exact path in the message: confirm the file exists (is_file / ls) and is readable by the PHP process user
  2. If it is missing, copy the shipped .dist file to the expected path (e.g. cp config/config.dist config/config) or fix the path passed to the constructor
  3. If the file exists but is empty, restore its contents — an empty file also triggers this error
  4. Run from the correct working directory or pass absolute paths so relative template paths resolve as intended

Example fix

// before
$template = new Template('config/config'); // file missing -> throws

// after
$file = __DIR__ . '/config/config';
if (!is_file($file) && is_file($file . '.dist')) {
    copy($file . '.dist', $file);
}
if (!is_file($file) || filesize($file) === 0) {
    throw new RuntimeException('Template file missing or empty: ' . $file);
}
$template = new Template($file);
Defensive patterns

Strategy: validation

Validate before calling

if (!is_file($file) || filesize($file) === 0) {
    if (is_file($file . '.dist')) {
        copy($file . '.dist', $file);
    } else {
        throw new RuntimeException('Template not found: ' . $file);
    }
}
$template = new Template($file);

Try / catch

try {
    $template = new Template($templateFile);
} catch (\SebastianBergmann\Template\InvalidArgumentException $e) {
    // surface a clear message about the missing/empty template path
}

Prevention

When it happens

Trigger: new Template($file) where $file does not exist, the path is misspelled or relative to the wrong CWD, the file exists but is not readable (permissions), the file is empty (0 bytes), or neither $file nor $file.'.dist' exists/readable/non-empty.

Common situations: Publishing mistakes where the real config/template was never copied and the .dist fallback is also absent (typical PHPUnit/php-code-generator setups that expect you to copy the .dist); application deployed without its templates directory; wrong base path passed after a refactor; file exists but is empty because a build step failed; open_basedir or permission issues making is_file()/file_get_contents() fail.

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 sebastianbergmann/php-text-template@1e6083ad3a (2026-09-14). Data as JSON: /api/errors/73b58c34289f5379. Report an issue: GitHub.

Appendix: source

Thrown at src/Template.php:124

        if (is_file($file)) {
            $template = file_get_contents($file);

            if (is_string($template) && $template !== '') {
                return $template;
            }
        }

        $distFile = $file . '.dist';

        if (is_file($distFile)) {
            $template = file_get_contents($distFile);

            if (is_string($template) && $template !== '') {
                return $template;
            }
        }

        throw new InvalidArgumentException(
            sprintf(
                'Failed to load template "%s"',
                $file,
            ),
        );
    }
}

View on GitHub (pinned to 1e6083ad3a)