{"record":{"id":"5c0a10d25ec53afd","repo":"ellite/Wallos","slug":"label-must-not-contain-a-colon-parametertrait","errorCode":null,"errorMessage":"Label must not contain a colon.","messagePattern":"Label must not contain a colon\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"libs/OTPHP/ParameterTrait.php","lineNumber":154,"sourceCode":"    public function setDigits(int $digits): void\n    {\n        $this->setParameter('digits', $digits);\n    }\n\n    public function setDigest(string $digest): void\n    {\n        $this->setParameter('algorithm', $digest);\n    }\n\n    /**\n     * @return array<non-empty-string, callable>\n     */\n    protected function getParameterMap(): array\n    {\n        return [\n            'label' => function (string $value): string {\n                assert($value !== '');\n                $this->hasColon($value) === false || throw new InvalidArgumentException(\n                    'Label must not contain a colon.'\n                );\n\n                return $value;\n            },\n            'secret' => static fn (string $value): string => strtoupper(trim($value, '=')),\n            'algorithm' => static function (string $value): string {\n                $value = strtolower($value);\n                in_array($value, hash_algos(), true) || throw new InvalidArgumentException(sprintf(\n                    'The \"%s\" digest is not supported.',\n                    $value\n                ));\n\n                return $value;\n            },\n            'digits' => static function ($value): int {\n                $value > 0 || throw new InvalidArgumentException('Digits must be at least 1.');\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/ellite/Wallos/blob/52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd/libs/OTPHP/ParameterTrait.php#L136-L172","documentation":"The 'label' entry in the parameter map validates every value assigned via setParameter('label', ...). RFC 4226/6238 provisioning URIs use a colon to separate issuer from account name, so a label containing a colon would corrupt the URI and is rejected with this InvalidArgumentException.","triggerScenarios":"Calling setParameter('label', 'my:user@example.com') or any label string containing ':', which happens when users paste email-like identifiers that already embed an issuer prefix.","commonSituations":"Putting 'Issuer:user@email' into the label because the developer confused the label with the full provisioning-URI path; copying the whole 'Issuer:account' part from a generated otpauth URI instead of just the account part.","solutions":["Pass only the account name as the label and set the issuer separately via setParameter('issuer', ...)","Strip the issuer prefix and colon from the string before assigning it","URL-encode is not a workaround; the colon check applies to the raw value, so remove the colon"],"exampleFix":"// before\n$otp->setLabel('Acme:alice@acme.com');\n// after\n$otp->setIssuer('Acme');\n$otp->setLabel('alice@acme.com');","handlingStrategy":"validation","validationCode":"$label = 'alice@acme.com';\nif (str_contains($label, ':')) {\n    throw new \\LogicException('Label must not contain a colon');\n}\n$otp->setLabel($label);","typeGuard":null,"tryCatchPattern":"try {\n    $otp->setLabel($userInput);\n} catch (\\InvalidArgumentException $e) {\n    $otp->setLabel(str_replace(':', '', $userInput));\n}","preventionTips":["Treat label = account only; issuer goes in setIssuer()","Sanitize user-supplied labels by stripping colons","Never copy the 'Issuer:account' string from a generated URI back into setLabel()"],"tags":["php","otp","provisioning-uri"],"backgroundTag":"invalid-argument-value","analyzedSha":"52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd","analyzedAt":"2026-09-13T14:09:30.873Z","contentChangedAt":"2026-09-13T14:09:30.873Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}