appwrite/appwrite · error · Exception
Invalid secret
Error message
Invalid secret
What it means
Thrown by Microsoft::getAppSecret() when json_decode() of the stored appSecret fails. The Microsoft adapter expects appSecret to be a JSON object (containing at least 'clientSecret' and 'tenantID'); JSON_THROW_ON_ERROR converts any syntax error into a JsonException, which is caught and re-thrown as this generic Exception. It fires on the first access to any field pulled from the secret (clientSecret, tenantID).
Source
Thrown at src/Appwrite/Auth/OAuth2/Microsoft.php:192
$headers = ['Authorization: Bearer ' . \urlencode($accessToken)];
$user = $this->request('GET', 'https://graph.microsoft.com/v1.0/me', $headers);
$this->user = \json_decode($user, true);
}
return $this->user;
}
/**
* Decode the JSON stored in appSecret
*
* @return array
*/
protected function getAppSecret(): array
{
try {
$secret = \json_decode($this->appSecret, true, 512, JSON_THROW_ON_ERROR);
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
/**
* Extracts the Client Secret from the JSON stored in appSecret
*
* @return string
*/
protected function getClientSecret(): string
{
$secret = $this->getAppSecret();
return $secret['clientSecret'] ?? '';
}
/**
* Extracts the Tenant Id from the JSON stored in appSecret.View on GitHub (pinned to cd368e707d)
Solutions
- Re-enter the Microsoft appSecret in the Console as well-formed JSON, e.g. {"clientSecret":"...","tenantID":"..."}.
- Run the value through json_decode locally (or a JSON linter) to find the exact syntax error before saving.
- Ensure no HTML entity encoding, smart quotes, or stray whitespace wraps the value; paste as plain text.
- If migrating from a raw-string format, wrap the existing secret into the JSON shape and re-save.
Example fix
// before
$appSecret = 'clientSecret=abc;tenantID=000-000'; // not JSON
// after
$appSecret = '{"clientSecret":"abc","tenantID":"00000000-0000-0000-0000-000000000000"}'; Defensive patterns
Strategy: validation
Validate before calling
// Validate that appSecret parses as JSON before persisting it for the Microsoft provider.
function validateMicrosoftSecretJSON(string $appSecret): void {
$decoded = json_decode($appSecret, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($decoded)) {
throw new InvalidArgumentException('Microsoft appSecret must decode to a JSON object.');
}
}
try {
validateMicrosoftSecretJSON($appSecret);
} catch (\JsonException | \InvalidArgumentException $e) {
// reject the save; surface the error to the admin
} Try / catch
// Around any code path that reads the Microsoft secret:
try {
$clientSecret = $microsoft->getClientSecret();
} catch (\Exception $e) {
if ($e->getMessage() === 'Invalid secret') {
throw new ProviderConfigurationException('Microsoft appSecret is not valid JSON; re-enter it as {"clientSecret":...,"tenantID":...}', 0, $e);
}
throw $e;
} Prevention
- Never store the Microsoft appSecret as a plain string; always use the JSON object shape.
- Add a JSON-schema validation step in the API/Console save handler for the Microsoft provider.
- Pin a contract test that builds the adapter from sample config and asserts getAppSecret() returns an array.
- Paste secrets as plain text from a trusted source to avoid HTML-entity/smart-quote corruption.
When it happens
Trigger: Any call to getClientSecret() or getTenantID() on a Microsoft adapter whose appSecret is not valid JSON: getLoginURL(), getTokens(), refreshTokens(), and verifyCredentials() all reach getAppSecret(). Triggered when a user starts a Microsoft OAuth2 login or the Console validates a provider whose secret was saved as a plain string, with a trailing comma, single-quoted, HTML-escaped, or otherwise malformed.
Common situations: Secret entered as a bare client-secret string instead of JSON; JSON hand-edited and broken (trailing comma, unescaped quotes); copy-paste from a webpage that inserted smart-quotes or HTML entities; secret saved through an older API that accepted raw strings; leading/trailing whitespace or BOM in the value.
Related errors
AI-assisted analysis of appwrite/appwrite@cd368e707d (2026-08-12).
Data as JSON: /api/errors/980d993b6c409e3b.
Report an issue: GitHub.