{"record":{"id":"00606bd520993923","repo":"eyaltoledano/claude-task-master","slug":"invalid-maxattempts-value-maxattempts-must-be","errorCode":null,"errorMessage":"Invalid maxAttempts value: ${maxAttempts}. Must be a positive integer.","messagePattern":"Invalid maxAttempts value: (.+?)\\. Must be a positive integer\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/auth/managers/auth-manager.ts","lineNumber":174,"sourceCode":"\t */\n\tasync verifyMFAWithRetry(\n\t\tfactorId: string,\n\t\tcodeProvider: () => Promise<string>,\n\t\toptions?: {\n\t\t\tmaxAttempts?: number;\n\t\t\tonInvalidCode?: (attempt: number, remaining: number) => void;\n\t\t}\n\t): Promise<MFAVerificationResult> {\n\t\tconst maxAttempts = options?.maxAttempts ?? 3;\n\t\tconst onInvalidCode = options?.onInvalidCode;\n\n\t\t// Guard against invalid maxAttempts values\n\t\tif (\n\t\t\t!Number.isFinite(maxAttempts) ||\n\t\t\t!Number.isInteger(maxAttempts) ||\n\t\t\tmaxAttempts < 1\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Invalid maxAttempts value: ${maxAttempts}. Must be a positive integer.`\n\t\t\t);\n\t\t}\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\tconst code = await codeProvider();\n\t\t\t\tconst credentials = await this.verifyMFA(factorId, code);\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tattemptsUsed: attempt,\n\t\t\t\t\tcredentials\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\t// Only retry on invalid MFA code errors\n\t\t\t\tif (\n\t\t\t\t\terror instanceof AuthenticationError &&\n\t\t\t\t\terror.code === 'INVALID_MFA_CODE'","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/auth/managers/auth-manager.ts#L156-L192","documentation":"A synchronous TypeError guard in verifyMFAWithRetry. The method retries MFA verification a bounded number of times, so maxAttempts must be a finite positive integer (>= 1). Values like 0, -1, NaN, Infinity, or non-integers are rejected before any verification attempt is made.","triggerScenarios":"Calling authManager.verifyMFAWithRetry(code, factorId, maxAttempts) with maxAttempts = 0, a negative number, NaN, Infinity, or a fractional value like 1.5 — typically from unvalidated CLI input or a bad config value.","commonSituations":"CLI parsing that yields NaN when a flag is omitted; config files where attempts is a string like '3'; off-by-one logic passing 0 to mean 'no retries' (author intent) but failing validation.","solutions":["Pass a positive integer, e.g. Math.max(1, Math.floor(Number(maxAttempts)))","Validate user/config input before calling: Number.isInteger(n) && n >= 1","If 0 was intended as 'single attempt, no retries', pass 1 instead"],"exampleFix":"// before\nawait auth.verifyMFAWithRetry(code, factorId, Number(opts.retries)); // NaN if flag missing\n// after\nconst retries = Number(opts.retries ?? 1);\nif (!Number.isInteger(retries) || retries < 1) throw new Error('retries must be a positive integer');\nawait auth.verifyMFAWithRetry(code, factorId, retries);","handlingStrategy":"validation","validationCode":"function isValidMaxAttempts(n: unknown): n is number {\n  return typeof n === 'number' && Number.isFinite(n) && Number.isInteger(n) && n >= 1;\n}\nif (!isValidMaxAttempts(maxAttempts)) maxAttempts = 1;","typeGuard":"function isPositiveInt(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 1;\n}","tryCatchPattern":"try {\n  await auth.verifyMFAWithRetry(code, factorId, maxAttempts);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('maxAttempts')) {\n    // programmer error: clamp and retry once with a valid value\n    await auth.verifyMFAWithRetry(code, factorId, 3);\n  } else throw e;\n}","preventionTips":["Always coerce and validate numeric CLI/config input before passing it","Use Math.floor + range checks when deriving attempts from user input","Never pass 0 to mean 'single attempt' — the minimum valid value is 1","Write unit tests covering NaN, 0, negatives, and fractional inputs"],"tags":["validation","mfa","argument-error"],"backgroundTag":"invalid-argument-value","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}