ellite/Wallos · error · InvalidArgumentException
The label is not set.
Error message
The label is not set.
What it means
OTP::generateURI (backing getProvisioningUri) requires a label; it throws InvalidArgumentException when getLabel() returns null. The otpauth URI scheme mandates otpauth://<type>/<label>, so a label must be set before a provisioning URI can be produced.
Solutions
- Call setLabel() before getProvisioningUri(): $totp->setLabel('alice@example.com').
- Include the label when creating: TOTP::create($secret, null, 'sha1', 6, 'alice@example.com').
- If loading from a URI, ensure the path segment (label) is present.
- Guard: if ($otp->getLabel() === null) { $otp->setLabel($defaultLabel); }
Example fix
// before
$totp = TOTP::create($secret);
$uri = $totp->getProvisioningUri(); // throws
// after
$totp = TOTP::create($secret);
$totp->setLabel('alice@example.com');
$uri = $totp->getProvisioningUri(); Defensive patterns
Strategy: validation
Validate before calling
if ($otp->getLabel() === null) {
$otp->setLabel($user->email);
}
$uri = $otp->getProvisioningUri(); Type guard
function hasLabel(object $otp): bool {
return is_string($otp->getLabel()) && $otp->getLabel() !== '';
} Try / catch
try {
$uri = $otp->getProvisioningUri();
} catch (InvalidArgumentException $e) {
$otp->setLabel('unknown-account');
$uri = $otp->getProvisioningUri();
} Prevention
- Make setLabel() part of your OTP enrollment flow before QR generation
- Store the label alongside the secret in your DB schema
- Wrap URI generation in a helper that enforces label presence
- Add a smoke test: create -> getProvisioningUri for every OTP type
When it happens
Trigger: Calling getProvisioningUri() on a TOTP/HOTP object created from a secret alone without calling setLabel(), e.g. TOTP::create($secret) then getProvisioningUri().
Common situations: Generating QR codes for authenticator apps before assigning an account label; refactors that dropped setLabel(); labels lost when objects were rebuilt from secrets stored in DB.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Unsupported " " OTP type
- Invalid "secret" parameter.
- Label must not contain a colon.
- Issuer must not contain a colon.
- Invalid "counter" parameter.
AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13).
Data as JSON: /api/errors/38828e5b9f896bda.
Report an issue: GitHub.
Appendix: source
Thrown at libs/OTPHP/OTP.php:102
] as $key => $default) {
if (isset($options[$key]) && $default === $options[$key]) {
unset($options[$key]);
}
}
ksort($options);
}
/**
* @param non-empty-string $type
* @param array<non-empty-string, mixed> $options
*
* @return non-empty-string
*/
protected function generateURI(string $type, array $options): string
{
$label = $this->getLabel();
is_string($label) || throw new InvalidArgumentException('The label is not set.');
$this->hasColon($label) === false || throw new InvalidArgumentException('Label must not contain a colon.');
$options = [...$options, ...$this->getParameters()];
$this->filterOptions($options);
$params = str_replace(['+', '%7E'], ['%20', '~'], http_build_query($options, '', '&'));
return sprintf(
'otpauth://%s/%s?%s',
$type,
rawurlencode(($this->getIssuer() !== null ? $this->getIssuer() . ':' : '') . $label),
$params
);
}
/**
* @param non-empty-string $safe
* @param non-empty-string $user
*/
protected function compareOTP(string $safe, string $user): boolView on GitHub (pinned to 52820e87ca)