{"record":{"id":"13d73298a5734dc2","repo":"chatboxai/chatbox","slug":"no-authorization-code-found-in-the-input","errorCode":null,"errorMessage":"No authorization code found in the input","messagePattern":"No authorization code found in the input","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/oauth/providers/anthropic.ts","lineNumber":99,"sourceCode":"      state: verifier,\n    })\n\n    const authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`\n    return { authUrl }\n  },\n\n  async exchangeCode(authInput: string) {\n    if (!pendingVerifier) {\n      throw new Error('No pending login flow. Call startLogin first.')\n    }\n\n    const verifier = pendingVerifier\n    pendingVerifier = null\n\n    const { code, state } = parseCallbackInput(authInput)\n\n    if (!code) {\n      throw new Error('No authorization code found in the input')\n    }\n\n    const response = await fetch(TOKEN_URL, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        grant_type: 'authorization_code',\n        client_id: CLIENT_ID,\n        code,\n        // Preserve the verifier-backed state on exchange as well, otherwise Anthropic rejects\n        // the flow even though this differs from a more typical OAuth implementation.\n        state: state || verifier,\n        redirect_uri: REDIRECT_URI,\n        code_verifier: verifier,\n      }),\n    })\n\n    if (!response.ok) {","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/main/oauth/providers/anthropic.ts#L81-L117","documentation":"Thrown by Anthropic's CodePaste OAuth provider inside exchangeCode() after parseCallbackInput() fails to extract an authorization code from the user-pasted input. Because the parser falls back to treating the trimmed input as a bare code, this branch is only reachable when the input is empty or pure whitespace, meaning the user submitted nothing or only the state/whitespace where a code was expected.","triggerScenarios":"Calling anthropicOAuthProvider.exchangeCode(''), exchangeCode('   '), or pasting only a fragment that contains no 'code=' parameter and no bare-code text (e.g. only '?state=xxx'). It also fires if startLogin was called but the user closed the browser and submitted an empty string.","commonSituations":"User clicks 'submit' on the paste dialog without pasting anything; user pastes only the redirect state; clipboard copy failed so the field is blank; automated test passes an empty string to exchangeCode().","solutions":["Validate that authInput.trim() is non-empty and looks like a URL, query string, or code before calling exchangeCode().","Show a clearer UI hint: 'Paste the full callback URL from the browser (it contains ?code=...)' so the user knows what to supply.","If parsing succeeds but code is missing, surface a specific message telling the user the pasted text had no code parameter rather than a generic error."],"exampleFix":"// before\nawait provider.exchangeCode(authInput)\n\n// after\nconst trimmed = authInput.trim()\nif (!trimmed) throw new Error('Paste the full callback URL or authorization code first.')\nif (!trimmed.includes('code=') && !trimmed.includes('#') && trimmed.length < 16) {\n  throw new Error('Input does not look like an authorization code or callback URL.')\n}\nawait provider.exchangeCode(trimmed)","handlingStrategy":"validation","validationCode":"function isValidCodeInput(authInput: unknown): authInput is string {\n  return typeof authInput === 'string' && authInput.trim().length > 0\n}\n\n// before calling exchangeCode:\nif (!isValidCodeInput(authInput)) {\n  throw new Error('Paste the full callback URL or authorization code first.')\n}\nawait provider.exchangeCode(authInput)","typeGuard":"function looksLikeCallbackOrCode(input: string): boolean {\n  const t = input.trim()\n  if (!t) return false\n  return t.includes('code=') || t.includes('#') || t.length >= 16\n}","tryCatchPattern":"try {\n  await provider.exchangeCode(authInput)\n} catch (e) {\n  if (/No authorization code/i.test(String(e))) {\n  // user input issue — re-prompt, do not retry with same value\n  }\n  throw e\n}","preventionTips":["Disable the submit button until the paste field has non-whitespace content.","Run parseCallbackInput on the input in the UI and show a live hint if no code is detected.","Trim the input before passing it to exchangeCode."],"tags":["oauth","validation","user-input","anthropic"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}