phacility/phabricator · error · Exception
Template "%s" is not a valid template.
Error message
Template "%s" is not a valid template.
What it means
PhabricatorMemeEngine::newAsset() renders a meme by first loading the template image via loadTemplateFile(); when that returns nothing (no macro/template file for the configured template name) it throws this exception. Note the interpolation passes the falsy $template, so the message renders as 'Template "" is not a valid template.' -- the useful information is which template name was set on the engine, not the interpolated value.
Source
Thrown at src/applications/macro/engine/PhabricatorMemeEngine.php:67
public function getGenerateURI() {
$params = array(
'macro' => $this->getTemplate(),
'above' => $this->getAboveText(),
'below' => $this->getBelowText(),
);
return new PhutilURI('/macro/meme/', $params);
}
public function newAsset() {
$cache = $this->loadCachedFile();
if ($cache) {
return $cache;
}
$template = $this->loadTemplateFile();
if (!$template) {
throw new Exception(
pht(
'Template "%s" is not a valid template.',
$template));
}
$hash = $this->newTransformHash();
$asset = $this->newAssetFile($template);
$xfile = id(new PhabricatorTransformedFile())
->setOriginalPHID($template->getPHID())
->setTransformedPHID($asset->getPHID())
->setTransform($hash);
try {
$caught = null;
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();View on GitHub (pinned to 5720a38cfe)
Solutions
- Open the Macro application and confirm a macro exists for the template name; use its exact name.
- Re-upload the missing template macro if it was deleted.
- If you control the call site, verify the template resolves before invoking newAsset() (see exampleFix).
Example fix
// before
$engine = id(new PhabricatorMemeEngine())
->setTemplateByName('nonexistent_template')
->setTopText('hi');
$asset = $engine->newAsset(); // throws
// after
$engine = id(new PhabricatorMemeEngine())
->setTemplateByName($valid_macro_name)
->setTopText('hi');
$asset = $engine->newAsset();
// guard before rendering when template comes from user input:
if (!$macro) {
return $this->newDialog()->setTitle(pht('Unknown Template'));
} Defensive patterns
Strategy: validation
Validate before calling
// Verify the template resolves before rendering a meme:
$template = $engine->loadTemplateFile();
if (!$template) {
return new Aphront404Response(); // or render 'unknown template' dialog
}
$asset = $engine->newAsset(); Type guard
function memeTemplateExists($template_name) {
$macro = id(new PhabricatorFileQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withNames(array($template_name))
->executeOne();
return (bool)$macro;
} Try / catch
try {
$asset = $engine->newAsset();
} catch (Exception $ex) {
// template macro missing (deleted or never uploaded); degrade gracefully
return $this->newDialog()->setTitle(pht('Unknown Meme Template'));
} Prevention
- Validate the template name against existing macros when accepting user input for memes.
- Do not delete macro images still referenced as meme templates; check references first.
- Note the exception message interpolates the falsy template value, so log the engine's configured name for debugging.
When it happens
Trigger: Requesting /macro/meme/ (or calling the meme engine) with a template name whose underlying template file/macro does not exist: template macro deleted after being referenced, name typo, or a fresh install missing default macro images.
Common situations: Custom meme templates removed or renamed; bookmarks/links embedding an old template name; macro images garbage collected or pruned.
Related errors
- Request parameter "%s" is not formatted properly. Expected a
- Request parameter "%s" is not formatted properly. Expected a
- Invalid Request (CSRF)
- This server is configured as "%s", but you are using the dom
- This service is configured to operate in cluster mode, but %
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/c892fd9a929304e5.
Report an issue: GitHub.