{"record":{"id":"6688f367ce8c2611","repo":"aaif-goose/goose","slug":"databricks-oauth-token-provider-is-not-configured","errorCode":null,"errorMessage":"Databricks OAuth token provider is not configured","messagePattern":"Databricks OAuth token provider is not configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-providers/src/databricks_auth.rs","lineNumber":80,"sourceCode":"                    None => {\n                        let fresh = self\n                            .token_resolver\n                            .as_ref()\n                            .and_then(|resolve| resolve())\n                            .unwrap_or_else(|| original.clone());\n                        *self.token_cache.lock().unwrap() = Some(fresh.clone());\n                        fresh\n                    }\n                }\n            }\n            DatabricksAuth::OAuth {\n                host,\n                client_id,\n                redirect_url,\n                scopes,\n            } => {\n                let Some(provider) = &self.oauth_token_provider else {\n                    anyhow::bail!(\"Databricks OAuth token provider is not configured\")\n                };\n                provider(\n                    host.clone(),\n                    client_id.clone(),\n                    redirect_url.clone(),\n                    scopes.clone(),\n                )\n                .await?\n            }\n        };\n        Ok((\"Authorization\".to_string(), format!(\"Bearer {token}\")))\n    }\n}\n","sourceCodeStart":62,"sourceCodeEnd":94,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-providers/src/databricks_auth.rs#L62-L94","documentation":"DatabricksAuthProvider was built in OAuth mode (DatabricksAuth::OAuth { host, client_id, redirect_url, scopes }) but its oauth_token_provider field is None, so get_auth_header() has no callback capable of minting/refreshing a token and bails immediately. goose's own databricks and databricks_v2 provider definitions always pass Some(oauth_token_provider(...)); only hand-rolled constructions of DatabricksAuthProvider can hit this.","triggerScenarios":"Constructing DatabricksAuthProvider directly (struct literal or via a builder that leaves oauth_token_provider unset) with auth = DatabricksAuth::oauth(host), then issuing any request, which calls get_auth_header().","commonSituations":"Library users embedding goose who copy the struct definition instead of calling databricks::from_config / databricks_v2 constructors; code paths that choose OAuth when no UI/daemon is available to complete the OAuth flow (the provider closure must exist regardless of whether a flow can run).","solutions":["Pass a token-provider closure when constructing: databricks.rs and databricks_v2.rs take Option<DatabricksOauthTokenProvider>; supply Some(provider) whenever auth is OAuth — see oauth_token_provider() in databricks_def.rs for a reference implementation","Prefer the high-level constructors (databricks::from_config, databricks_v2::...) which wire the provider for you","If you only have a PAT, use DatabricksAuth::Token(token) instead of OAuth mode"],"exampleFix":"// before\nlet auth_method = AuthMethod::Custom(Box::new(DatabricksAuthProvider {\n    auth: DatabricksAuth::oauth(host.clone()),\n    token_cache: Arc::new(Mutex::new(None)),\n    oauth_token_provider: None, // -> bails on first request\n    token_resolver: None,\n}));\n\n// after\nlet auth_method = AuthMethod::Custom(Box::new(DatabricksAuthProvider {\n    auth: DatabricksAuth::oauth(host.clone()),\n    token_cache: Arc::new(Mutex::new(None)),\n    oauth_token_provider: Some(my_token_provider), // Fn(host, id, redirect, scopes) -> Future<Result<String>>\n    token_resolver: None,\n}));","handlingStrategy":"type-guard","validationCode":"fn oauth_auth_ready(auth: &DatabricksAuth, provider: &Option<DatabricksOauthTokenProvider>) -> bool {\n    !(matches!(auth, DatabricksAuth::OAuth { .. }) && provider.is_none())\n}","typeGuard":"fn needs_oauth_provider(auth: &DatabricksAuth) -> bool {\n    matches!(auth, DatabricksAuth::OAuth { .. })\n}\n// Guard at construction:\nif needs_oauth_provider(&auth) {\n    anyhow::ensure!(oauth_provider.is_some(), \"OAuth auth requires a token provider closure\");\n}","tryCatchPattern":"match provider.get_auth_header().await {\n    Err(e) if e.to_string().contains(\"token provider is not configured\") =>\n        return Err(anyhow!(\"construction bug: build this provider via databricks::from_config which wires OAuth\")),\n    r => r?,\n}","preventionTips":["Never construct DatabricksAuthProvider by struct literal for OAuth mode; use databricks::from_config / databricks_v2 constructors that inject the token provider","Add a unit test asserting oauth_token_provider.is_some() whenever auth is DatabricksAuth::OAuth","If OAuth isn't feasible in your embedding (headless CI), use DatabricksAuth::Token with a PAT"],"tags":["databricks","oauth","provider-setup","api-misuse"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}