symfony/translation · error · InvalidResourceException
The pgs:switch attribute must not be empty.
Error message
The pgs:switch attribute must not be empty.
What it means
In XLIFF 2.0 files using the pgs (translation provenance/skeleton) extension, the pgs:switch attribute selects which sub-element to use. The loader throws InvalidResourceException when this attribute is present but empty (or whitespace only), because no switch criteria can be derived.
Solutions
- Populate the pgs:switch attribute with space-separated type:variable tokens (e.g. "env:BRANCH os:PLATFORM").
- Remove the pgs:switch attribute entirely if switching is not needed.
- Open the file in the exporting tool and re-export with the extension settings completed.
Example fix
// before <unit id="u1" pgs:switch="">...</unit> // after <unit id="u1" pgs:switch="env:BRANCH">...</unit>
Defensive patterns
Strategy: validation
Validate before calling
$xml = simplexml_load_file($resource);
foreach ($xml->xpath('//*[@pgs:switch]') ?: [] as $el) {
if ('' === trim((string) $el->attributes('pgs', true)->switch ?? '')) {
throw new \RuntimeException('Empty pgs:switch in '.$resource);
}
} Try / catch
try {
$catalogue = $loader->load($resource, $locale);
} catch (InvalidResourceException $e) {
if (str_contains($e->getMessage(), 'pgs:switch attribute must not be empty')) {
// fix or strip the pgs:switch attribute
}
throw $e;
} Prevention
- Keep pgs extension attributes complete when the exporting tool emits them.
- Strip unsupported/empty extension attributes before loading if unused.
- Add schema/custom lint checks for pgs attributes in CI.
When it happens
Trigger: Loading an XLIFF 2.0 file whose <unit> (pgs unit) carries pgs:switch="" or pgs:switch=" ", reaching parsePgsSwitch via extractXliff2PgsUnit.
Common situations: Translation tooling that emits the pgs:switch attribute without populating it; hand-edited XLIFF where the variable mapping was deleted.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- The pgs:switch token
- Loading translations from the Xliff format requires the…
- This is not a local file
- File " " not found.
- This is neither a file nor an XLIFF string
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/55b49f9e3e40727d.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/XliffFileLoader.php:256
$metadata = ['pgs-switch' => $pgsSwitch];
if (isset($unit->notes)) {
$metadata['notes'] = [];
foreach ($unit->notes->note as $noteNode) {
$note = array_map('strval', $noteNode->attributes() ?? []);
$note['content'] = (string) $noteNode;
$metadata['notes'][] = $note;
}
}
$catalogue->setMetadata($source, $metadata, $intlDomain);
}
private function parsePgsSwitch(string $pgsSwitch): array
{
$trimmed = trim($pgsSwitch);
if ('' === $trimmed) {
throw new InvalidResourceException('The pgs:switch attribute must not be empty.');
}
$switches = [];
foreach (preg_split('/\s+/', $trimmed) as $item) {
$parts = explode(':', $item, 2);
if (2 !== \count($parts) || '' === $parts[0] || '' === $parts[1]) {
throw new InvalidResourceException(\sprintf('The pgs:switch token "%s" must use the "type:variable" form.', $item));
}
$switches[] = ['type' => $parts[0], 'variable' => $parts[1]];
}
return $switches;
}
private function extractPgsSegmentText(\SimpleXMLElement $element, array $switches): string
{
$pluralVariables = [];
foreach ($switches as $switch) {View on GitHub (pinned to ae9e8a51bc)