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
- Check the exact path in the message: confirm the file exists (is_file / ls) and is readable by the PHP process user
- 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
- If the file exists but is empty, restore its contents — an empty file also triggers this error
- 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
- Ship the .dist file and document that users must copy it to the real name before first run
- Resolve template paths against __DIR__ or a configured base path, not the CWD
- Check is_file() and non-empty size before constructing Template
- Verify deploy scripts include the templates/config directory
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)