{"record":{"id":"6a22f5c391cc73c5","repo":"RocketChat/Rocket.Chat","slug":"error-challenge-not-found","errorCode":"error-challenge-not-found","errorMessage":"challenge not found","messagePattern":"challenge not found","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/twoFactorChallenges.ts","lineNumber":26,"sourceCode":"import { emailCheckForOAuth, getTwoFAMethodForOAuth } from '../../lib/oauth/twoFactorAuth';\nimport { generateConnection } from '../ApiClass';\nimport { API } from '../api';\n\nAPI.v1.addRoute(\n\t'twoFactorChallenges.sendEmailCode',\n\t{ validateParams: isTwoFactorChallengesSendEmailCodeParamsPOST, rateLimiterOptions: { intervalTimeInMS: 60000, numRequestsAllowed: 5 } },\n\t{\n\t\tasync post() {\n\t\t\tconst { challengeId } = this.bodyParams;\n\n\t\t\tif (!challengeId) {\n\t\t\t\tthrow new Meteor.Error('error-parameter-required', 'challengeId is required');\n\t\t\t}\n\n\t\t\tconst challenge = await TwoFactorChallenges.findOneByPendingChallengeId(challengeId);\n\n\t\t\tif (!challenge) {\n\t\t\t\tthrow new Meteor.Error('error-challenge-not-found', 'challenge not found');\n\t\t\t}\n\n\t\t\tif (challenge.expireAt && challenge.expireAt < new Date()) {\n\t\t\t\tthrow new Meteor.Error('error-challenge-expired', 'challenge expired');\n\t\t\t}\n\n\t\t\tif (challenge.method !== 'email') {\n\t\t\t\tthrow new Meteor.Error('error-invalid-challenge-method', 'invalid challenge method');\n\t\t\t}\n\n\t\t\tconst { userId } = challenge;\n\n\t\t\tconst user = await getUserForCheck(userId);\n\n\t\t\tif (!user) {\n\t\t\t\tthrow new Meteor.Error('error-user-not-found', 'user not found');\n\t\t\t}\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/twoFactorChallenges.ts#L8-L44","documentation":"Thrown by POST twoFactorChallenges.sendEmailCode when TwoFactorChallenges.findOneByPendingChallengeId returns nothing — no pending challenge document exists for that id. Challenges are short-lived, single-flow records created during an OAuth login that requires email 2FA; once resolved, expired, or removed they no longer match.","triggerScenarios":"POST with a challengeId from a login attempt that already completed; a challenge removed after too many failed verify attempts (the verify endpoint deletes it); a mistyped or truncated id; calling sendEmailCode long after the initial login started.","commonSituations":"User leaves the 2FA page open, pastes the code much later, clicks resend, and the challenge is gone; retrying an old flow from a deep-linked page; double-submit racing where one branch finishes the challenge first.","solutions":["Restart the OAuth login flow to create a fresh challenge, then resend the code","Handle this error as 'restart flow', not 'show generic failure' — no retry of the same call can succeed","Make sure only one component drives the challenge; parallel resends/verifies consume it","Keep the challenge-to-page lifetime short in the UI"],"exampleFix":"// before\nawait retry(() => sdk.post('twoFactorChallenges.sendEmailCode', { challengeId })); // hopeless once deleted\n// after\ntry {\n  await sdk.post('twoFactorChallenges.sendEmailCode', { challengeId });\n} catch (e) {\n  if (e.error === 'error-challenge-not-found') window.location = oauthLoginUrl; // restart flow\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await sdk.post('twoFactorChallenges.sendEmailCode', { challengeId }); } catch (e) { if (e?.error === 'error-challenge-not-found') window.location = oauthLoginUrl; else throw e; }","preventionTips":["Map error-challenge-not-found to 'restart login flow' in every 2FA client","Never auto-retry the same challengeId after failure","Drive the challenge from a single component to avoid concurrent consumers"],"tags":["rest-api","two-factor","oauth","not-found","authentication"],"backgroundTag":"challenge-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}