{"record":{"id":"a78587ecae5ce426","repo":"Kuberwastaken/claurst","slug":"valid-oauth-authorize-base-url","errorCode":null,"errorMessage":"valid OAuth authorize base URL","messagePattern":"valid OAuth authorize base URL","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-rust/crates/core/src/lib.rs","lineNumber":4323,"sourceCode":"        let u1 = uuid::Uuid::new_v4();\n        let u2 = uuid::Uuid::new_v4();\n        bytes[..16].copy_from_slice(u1.as_bytes());\n        bytes[16..].copy_from_slice(u2.as_bytes());\n        base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes)\n    }\n\n    // ---- URL builder ----\n\n    /// Build an OAuth authorization URL with all required PKCE parameters.\n    pub fn build_auth_url(\n        authorize_base: &str,\n        code_challenge: &str,\n        state: &str,\n        callback_port: u16,\n        is_manual: bool,\n    ) -> String {\n        let mut u = url::Url::parse(authorize_base)\n            .expect(\"valid OAuth authorize base URL\");\n        {\n            let mut q = u.query_pairs_mut();\n            q.append_pair(\"code\", \"true\"); // tells the login page to show Claude Max upsell\n            q.append_pair(\"client_id\", CLIENT_ID);\n            q.append_pair(\"response_type\", \"code\");\n            let redirect = if is_manual {\n                MANUAL_REDIRECT_URL.to_string()\n            } else {\n                format!(\"http://localhost:{}/callback\", callback_port)\n            };\n            q.append_pair(\"redirect_uri\", &redirect);\n            q.append_pair(\"scope\", &ALL_SCOPES.join(\" \"));\n            q.append_pair(\"code_challenge\", code_challenge);\n            q.append_pair(\"code_challenge_method\", \"S256\");\n            q.append_pair(\"state\", state);\n        }\n        u.to_string()\n    }","sourceCodeStart":4305,"sourceCodeEnd":4341,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/core/src/lib.rs#L4305-L4341","documentation":"This panic fires when the OAuth authorize base URL passed into the Anthropic OAuth authorize-URL builder cannot be parsed by the `url` crate. The function assumes callers supply an absolute, well-formed HTTP(S) URL and uses expect to convert a parse failure into a panic with the message \"valid OAuth authorize base URL\".","triggerScenarios":"Invoking the authorize-URL builder (with code_challenge, state, callback_port, is_manual) with an `authorize_base` that is not a valid absolute URL — e.g. a relative path, an empty string, a URL missing a scheme, or a mistyped constant.","commonSituations":"A settings/config override pointing the authorize endpoint at a malformed value; trimming or joining logic that stripped the scheme; environments (self-hosted proxies, corporate gateways) where users set a custom authorize base; a refactor changing the constant from absolute to host-relative.","solutions":["Print/inspect the `authorize_base` argument; run it through `url::Url::parse` yourself to see the exact parse error.","Ensure the value is an absolute URL including scheme (e.g. `https://claude.ai/oauth/authorize`), not a relative path or bare host.","If it comes from user config, validate it at config-load time (parse once, reject invalid values with a clear message).","Change the function to return `Result<String, url::ParseError>` so a bad base becomes a user-facing error instead of a panic."],"exampleFix":"// before\nlet mut u = url::Url::parse(authorize_base)\n    .expect(\"valid OAuth authorize base URL\");\n// after\nlet mut u = url::Url::parse(authorize_base)\n    .map_err(|e| OAuthError::InvalidAuthorizeUrl(format!(\"{authorize_base}: {e}\")))?;","handlingStrategy":"validation","validationCode":"// Validate authorize_base before calling the builder:\nfn valid_authorize_base(s: &str) -> bool {\n    url::Url::parse(s)\n        .map(|u| matches!(u.scheme(), \"https\" | \"http\") && u.host_str().is_some())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"// Panic, not Result — guard the call site:\nlet url = std::panic::catch_unwind(|| build_authorize_url(base, &challenge, &state, port, manual))\n    .map_err(|_| OAuthError::InvalidAuthorizeUrl(base.to_string()))?;","preventionTips":["Store the authorize base as a parsed url::Url in config, not a raw string","Reject relative or scheme-less URLs at settings-load time","Keep the default constant absolute (https://...) and require the same for overrides","Log the offending string before parsing in debug builds"],"tags":["rust","oauth","url-parsing","panic","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}