{"record":{"id":"0efd79c031e09a2d","repo":"symfony/translation","slug":"the-pgs-switch-token-s-must-use-the-type-variable-form","errorCode":null,"errorMessage":"The pgs:switch token \"%s\" must use the \"type:variable\" form.","messagePattern":"The pgs:switch token \"(.+?)\" must use the \"type:variable\" form\\.","errorType":"exception","errorClass":"InvalidResourceException","httpStatus":null,"severity":"error","filePath":"Loader/XliffFileLoader.php","lineNumber":263,"sourceCode":"                $metadata['notes'][] = $note;\n            }\n        }\n\n        $catalogue->setMetadata($source, $metadata, $intlDomain);\n    }\n\n    private function parsePgsSwitch(string $pgsSwitch): array\n    {\n        $trimmed = trim($pgsSwitch);\n        if ('' === $trimmed) {\n            throw new InvalidResourceException('The pgs:switch attribute must not be empty.');\n        }\n\n        $switches = [];\n        foreach (preg_split('/\\s+/', $trimmed) as $item) {\n            $parts = explode(':', $item, 2);\n            if (2 !== \\count($parts) || '' === $parts[0] || '' === $parts[1]) {\n                throw new InvalidResourceException(\\sprintf('The pgs:switch token \"%s\" must use the \"type:variable\" form.', $item));\n            }\n            $switches[] = ['type' => $parts[0], 'variable' => $parts[1]];\n        }\n\n        return $switches;\n    }\n\n    private function extractPgsSegmentText(\\SimpleXMLElement $element, array $switches): string\n    {\n        $pluralVariables = [];\n        foreach ($switches as $switch) {\n            if ('plural' === $switch['type'] || 'ordinal' === $switch['type']) {\n                $pluralVariables[$switch['variable']] = true;\n            }\n        }\n\n        return $this->collectPgsText(dom_import_simplexml($element), $pluralVariables);\n    }","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Loader/XliffFileLoader.php#L245-L281","documentation":"Each whitespace-separated token in a pgs:switch attribute must be of the form type:variable. A token lacking the colon, or with an empty type or variable part, makes the loader throw InvalidResourceException naming the offending token.","triggerScenarios":"Loading an XLIFF 2.0 pgs unit whose pgs:switch contains a malformed token such as \"env\" (no colon), \":BRANCH\" (empty type), or \"env:\" (empty variable).","commonSituations":"Hand-authored pgs extensions; tooling bugs emitting half-formed switch expressions; copy/paste edits that dropped the variable part.","solutions":["Rewrite each token as type:variable with non-empty parts, e.g. \"env:BRANCH os:PLATFORM\".","Check for stray whitespace/typos splitting a token incorrectly (the loader splits on any whitespace).","Re-export the file from the tool with the pgs extension correctly configured."],"exampleFix":"// before\n<unit id=\"u1\" pgs:switch=\"env: os\">...</unit>\n// after\n<unit id=\"u1\" pgs:switch=\"env:BRANCH os:PLATFORM\">...</unit>","handlingStrategy":"validation","validationCode":"foreach (preg_split('/\\s+/', trim($pgsSwitch)) as $token) {\n    if (!preg_match('/^[^:\\s]+:[^:\\s]+$/', $token)) {\n        throw new \\InvalidArgumentException(sprintf('Bad pgs:switch token: %s', $token));\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $catalogue = $loader->load($resource, $locale);\n} catch (InvalidResourceException $e) {\n    if (str_contains($e->getMessage(), 'must use the \"type:variable\" form')) {\n        // rewrite tokens as type:variable per the message\n    }\n    throw $e;\n}","preventionTips":["Enforce the type:variable token format whenever generating pgs:switch values.","Avoid manual editing of pgs attributes; regenerate from tooling.","Unit-test XLIFF fixtures containing pgs extensions."],"tags":["php","xliff","xliff-2","invalid-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"ae9e8a51bc29780d63c7f9efd6005d7c875e100b","analyzedAt":"2026-09-15T22:29:15.305Z","contentChangedAt":"2026-09-15T22:29:15.305Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}