{"record":{"id":"24463ae3b2fad423","repo":"zeroclaw-labs/zeroclaw","slug":"no-oauth-code-provided-24463a","errorCode":null,"errorMessage":"No OAuth code provided","messagePattern":"No OAuth code provided","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-providers/src/auth/openai_oauth.rs","lineNumber":296,"sourceCode":"\n    let code = parse_code_from_redirect(path, Some(expected_state))?;\n\n    let body =\n        \"<html><body><h2>ZeroClaw login complete</h2><p>You can close this tab.</p></body></html>\";\n    let response = format!(\n        \"HTTP/1.1 200 OK\\r\\nContent-Type: text/html; charset=utf-8\\r\\nContent-Length: {}\\r\\nConnection: close\\r\\n\\r\\n{}\",\n        body.len(),\n        body\n    );\n    let _ = stream.write_all(response.as_bytes()).await;\n\n    Ok(code)\n}\n\npub fn parse_code_from_redirect(input: &str, expected_state: Option<&str>) -> Result<String> {\n    let trimmed = input.trim();\n    if trimmed.is_empty() {\n        anyhow::bail!(\"No OAuth code provided\");\n    }\n\n    let query = if let Some((_, right)) = trimmed.split_once('?') {\n        right\n    } else {\n        trimmed\n    };\n\n    let params = parse_query_params(query);\n    let is_callback_payload = trimmed.contains('?')\n        || params.contains_key(\"code\")\n        || params.contains_key(\"state\")\n        || params.contains_key(\"error\");\n\n    if let Some(err) = params.get(\"error\") {\n        let desc = params\n            .get(\"error_description\")\n            .cloned()","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/auth/openai_oauth.rs#L278-L314","documentation":"parse_code_from_redirect takes the pasted redirect URL (or bare code) and first trims it; an empty (or whitespace-only) input bails here before any URL/query parsing or state checking. It is the input-validation gate for `auth paste-redirect` and the loopback receiver, so it means nothing was pasted, not that the paste was malformed.","triggerScenarios":"Calling `zeroclaw auth paste-redirect` and submitting an empty prompt/EOF (piped stdin closed early), or programmatically calling parse_code_from_redirect with an empty string in tests/wrappers.","commonSituations":"Piping an unset variable into the paste prompt (`zeroclaw ... | xclip` style automation), scripts reading the clipboard before it is populated, or interactive prompts exited with Ctrl-D.","solutions":["Paste the full redirect URL copied from the browser address bar after consent (or the bare code) and press Enter","In automation, verify the clipboard/stdin variable is non-empty before feeding it to the command","If the redirect URL is long and wraps in the terminal, paste as one line — a mangled empty paste triggers this too"],"exampleFix":"// before: feeding possibly-empty input\nlet code = parse_code_from_redirect(&pasted, Some(state))?;\n\n// after: guard empty input with a clearer message\nlet trimmed = pasted.trim();\nif trimmed.is_empty() {\n    anyhow::bail!(\"Nothing pasted — copy the redirect URL from the browser and retry\");\n}\nlet code = parse_code_from_redirect(trimmed, Some(state))?;","handlingStrategy":"validation","validationCode":"let trimmed = input.trim();\nif trimmed.is_empty() {\n    anyhow::bail!(\"no redirect URL pasted — copy the browser URL after consent and retry\");\n}\nlet code = openai_oauth::parse_code_from_redirect(trimmed, expected_state)?;","typeGuard":"fn has_redirect_payload(input: &str) -> bool {\n    !input.trim().is_empty()\n}","tryCatchPattern":"match openai_oauth::parse_code_from_redirect(&pasted, Some(state)) {\n    Err(e) if e.to_string() == \"No OAuth code provided\" => {\n        eprintln!(\"nothing was pasted — paste the full redirect URL and press Enter\");\n        continue; // re-prompt\n    }\n    other => other?,\n}","preventionTips":["Validate clipboard/stdin content is non-empty before feeding paste-redirect","Copy the URL from the browser address bar only after consent completes"],"tags":["oauth2","redirect-uri","validation","empty-string","cli"],"backgroundTag":"oauth-redirect-missing-code","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}