{"record":{"id":"1cae1bb17f1eded2","repo":"passbolt/passbolt_api","slug":"no-mfa-provider-set","errorCode":null,"errorMessage":"No MFA provider set.","messagePattern":"No MFA provider set\\.","errorType":"exception","errorClass":"RecordNotFoundException","httpStatus":404,"severity":"error","filePath":"plugins/PassboltCe/MultiFactorAuthentication/src/Utility/MfaAccountSettings.php","lineNumber":141,"sourceCode":"     * Return MfaSettings as JSON object\n     *\n     * @return string|false\n     */\n    public function toJson(): string|false\n    {\n        return json_encode($this->settings);\n    }\n\n    /**\n     * Return all providers\n     *\n     * @throws \\Cake\\Datasource\\Exception\\RecordNotFoundException if there is no provider set\n     * @return array list of providers\n     */\n    protected function getProviders(): array\n    {\n        if (!isset($this->settings[self::PROVIDERS])) {\n            throw new RecordNotFoundException(__('No MFA provider set.'));\n        }\n\n        return $this->settings[self::PROVIDERS];\n    }\n\n    /**\n     * Get an array of provider name that are enabled and verified for this user\n     *\n     * @throws \\Cake\\Datasource\\Exception\\RecordNotFoundException\n     * @return array\n     */\n    public function getEnabledProviders(): array\n    {\n        $result = [];\n        $providers = $this->getProviders();\n        foreach ($providers as $provider) {\n            if ($this->isProviderReady($provider)) {\n                $result[] = $provider;","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/MultiFactorAuthentication/src/Utility/MfaAccountSettings.php#L123-L159","documentation":"MfaAccountSettings::getProviders() returns the list of MFA providers enabled for a user account. It throws RecordNotFoundException when the internal settings array has no 'providers' key, meaning the account has no MFA configuration stored (or an empty/incomplete settings array was constructed).","triggerScenarios":"Calling getEnabledProviders() or disableProvider() on a MfaAccountSettings object whose settings array lacks the PROVIDERS key — e.g. built from an empty or partial account settings payload for a user who never enabled MFA.","commonSituations":"Checking a user's MFA status before they ever enrolled; account settings stored in OrganizationSettings are null/empty; after a data wipe or migration that dropped the mfa_accounts_settings payload; code paths that skip the isProviderEnabled/hasProviders pre-check.","solutions":["Check the user has MFA enabled before calling: guard with MfaAccountSettings retrieval or a settings isset/empty check.","Wrap the call in try/catch on \\Cake\\Datasource\\Exception\\RecordNotFoundException and treat the user as having no providers.","Verify the account settings payload passed to the constructor actually contains the 'providers' key.","If enrollment was expected, have the user complete MFA setup so settings get persisted."],"exampleFix":"// before\n$providers = $mfaAccountSettings->getEnabledProviders();\n// after\ntry {\n    $providers = $mfaAccountSettings->getEnabledProviders();\n} catch (\\Cake\\Datasource\\Exception\\RecordNotFoundException $e) {\n    $providers = [];\n}","handlingStrategy":"try-catch","validationCode":"$providers = [];\ntry {\n    $providers = $mfaAccountSettings->getEnabledProviders();\n} catch (\\Cake\\Datasource\\Exception\\RecordNotFoundException $e) {}","typeGuard":"$hasProviders = isset($mfaAccountSettings->toArray()[MfaSettings::PROVIDERS]);","tryCatchPattern":"try { $providers = $s->getEnabledProviders(); } catch (\\Cake\\Datasource\\Exception\\RecordNotFoundException $e) { $providers = []; }","preventionTips":["Always treat 'no record' as 'no MFA enabled' when reading account settings","Check MFA enrollment status before reading provider details","Guard code that runs for all users, since most have no MFA settings"],"tags":["mfa","record-not-found","settings"],"backgroundTag":"record-not-found","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}