ellite/Wallos · error · InvalidArgumentException

Issuer must not contain a colon.

Error message

Issuer must not contain a colon.

What it means

Like the label, the 'issuer' parameter is validated by the parameter map: setParameter('issuer', ...) rejects values containing a colon because the issuer occupies the provider part of an otpauth:// URI where colons are structural separators.

Solutions

  1. Remove the colon from the issuer name, e.g. 'My Company' instead of 'My:Company'
  2. Keep issuer and label separate: issuer is the provider, label is the account
  3. Sanitize the configured issuer with str_replace(':', '', $value) before assigning

Example fix

// before
$otp->setIssuer('Acme:EU');
// after
$otp->setIssuer('Acme EU');
Defensive patterns

Strategy: validation

Validate before calling

$issuer = preg_replace('/[:]/', ' ', $config['issuer'] ?? '');
if ($issuer !== '') {
    $otp->setIssuer($issuer);
}

Try / catch

try {
    $otp->setIssuer($issuer);
} catch (\InvalidArgumentException $e) {
    $otp->setIssuer(str_replace(':', '', $issuer));
}

Prevention

When it happens

Trigger: Calling setIssuer('My:Company') or setParameter('issuer', ...) with any string containing ':'; often occurs when the issuer string was assembled from 'brand:region' style identifiers.

Common situations: Company display names copied from internal naming conventions that include colons; storing the full 'Issuer:account' string in the issuer field by mistake.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13). Data as JSON: /api/errors/e857e00d67d38ccf. Report an issue: GitHub.

Appendix: source

Thrown at libs/OTPHP/ParameterTrait.php:177

            },
            'secret' => static fn (string $value): string => strtoupper(trim($value, '=')),
            'algorithm' => static function (string $value): string {
                $value = strtolower($value);
                in_array($value, hash_algos(), true) || throw new InvalidArgumentException(sprintf(
                    'The "%s" digest is not supported.',
                    $value
                ));

                return $value;
            },
            'digits' => static function ($value): int {
                $value > 0 || throw new InvalidArgumentException('Digits must be at least 1.');

                return (int) $value;
            },
            'issuer' => function (string $value): string {
                assert($value !== '');
                $this->hasColon($value) === false || throw new InvalidArgumentException(
                    'Issuer must not contain a colon.'
                );

                return $value;
            },
        ];
    }

    /**
     * @param non-empty-string $value
     */
    private function hasColon(string $value): bool
    {
        $colons = [':', '%3A', '%3a'];
        foreach ($colons as $colon) {
            if (str_contains($value, $colon)) {
                return true;
            }

View on GitHub (pinned to 52820e87ca)