{"record":{"id":"6e8909ddd952ee11","repo":"block/buzz","slug":"databricks-v2-model-discovery-failed-workspace-en","errorCode":null,"errorMessage":"Databricks v2 model discovery failed: workspace endpoint catalog: {workspace}; Unity Catalog model-service catalog: {unity_catalog}","messagePattern":"Databricks v2 model discovery failed: workspace endpoint catalog: (.+?); Unity Catalog model-service catalog: (.+?)","errorType":"exception","errorClass":"AgentError","httpStatus":null,"severity":"error","filePath":"crates/buzz-agent/src/catalog.rs","lineNumber":398,"sourceCode":"}\n\nfn catalog_error_kind(error: &AgentError) -> &'static str {\n    match error {\n        AgentError::InvalidParams(_) => \"invalid-params\",\n        AgentError::Llm(_) => \"llm\",\n        AgentError::LlmAuth(_) => \"auth\",\n        AgentError::LlmModelNotFound(_) => \"model-not-found\",\n        AgentError::LlmContextExceeded(_) => \"context-exceeded\",\n        AgentError::UnsupportedImageInput(_) => \"unsupported-image\",\n        AgentError::Mcp(_) => \"mcp\",\n        AgentError::Cancelled => \"cancelled\",\n    }\n}\n\nfn combined_catalog_error(workspace: AgentError, unity_catalog: AgentError) -> AgentError {\n    let auth_failure = matches!(&workspace, AgentError::LlmAuth(_))\n        || matches!(&unity_catalog, AgentError::LlmAuth(_));\n    let message = format!(\n        \"Databricks v2 model discovery failed: workspace endpoint catalog: {workspace}; Unity Catalog model-service catalog: {unity_catalog}\"\n    );\n    if auth_failure {\n        AgentError::LlmAuth(message)\n    } else {\n        AgentError::Llm(message)\n    }\n}\n\nfn merge_v2_models(\n    workspace: Vec<V2Endpoint>,\n    mut unity_catalog: Vec<ModelEntry>,\n    filter: Option<&DatabricksModelFilter>,\n    allow_known_model_fallback: bool,\n) -> Vec<ModelEntry> {\n    let mut seen_ids = HashSet::new();\n    let mut merged = Vec::with_capacity(workspace.len() + unity_catalog.len());\n","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-agent/src/catalog.rs#L380-L416","documentation":"`combined_catalog_error` merges two independent Databricks v2 model-discovery failures (the workspace endpoint catalog fetch and the Unity Catalog model-service catalog fetch) into a single AgentError. The message embeds both underlying errors; if either source error is `AgentError::LlmAuth`, the combined error is classified as `LlmAuth` (auth problem), otherwise a plain `Llm` error. It is raised by `fetch_v2_models_with_policy` when both discovery paths fail.","triggerScenarios":"Calling Databricks model discovery when the workspace serving-endpoint list API fails AND the Unity Catalog model-service list fails — e.g. expired/missing Databricks token, wrong workspace URL, network egress blocked, or the catalog/schema does not exist for this token.","commonSituations":"Expired PAT/OAuth token (yields LlmAuth classification), misconfigured DATABRICKS_HOST or workspace URL, service principal lacking permissions on unity_catalog models, corporate proxy blocking the workspace endpoint, or Databricks API version drift.","solutions":["Check the embedded sub-errors: if either mentions auth/401/403, refresh the Databricks token or service-principal credentials first.","Verify DATABRICKS_HOST and the workspace URL are correct and reachable (curl the /api/2.0/serving-endpoints endpoint).","Grant the token's principal permission to list serving endpoints and to the target Unity Catalog model catalog/schema.","Check network egress/proxy settings; both catalogs failing together usually indicates connectivity, not per-model config.","If permissions are fine, confirm the Databricks API responses haven't changed shape (SDK version drift)."],"exampleFix":"// before\nlet token = std::env::var(\"DATABRICKS_TOKEN\")?; // expired or empty -> both catalogs 401\n// after\nlet token = std::env::var(\"DATABRICKS_TOKEN\")?;\nif token.is_empty() {\n    return Err(AgentError::LlmAuth(\"DATABRICKS_TOKEN is empty; refresh credentials before model discovery\".into()));\n}\n// probe auth early so discovery reports one clear cause:\nclient.list_serving_endpoints().await.map_err(|e| AgentError::LlmAuth(format!(\"databricks auth probe failed: {e}\")))?;","handlingStrategy":"validation","validationCode":"// validate Databricks config and auth before model discovery\nlet token = std::env::var(\"DATABRICKS_TOKEN\").map_err(|_| \"DATABRICKS_TOKEN not set\")?;\nlet host = std::env::var(\"DATABRICKS_HOST\").map_err(|_| \"DATABRICKS_HOST not set\")?;\nassert!(!token.is_empty() && host.starts_with(\"https://\"), \"valid DATABRICKS_HOST (https://...) and non-empty DATABRICKS_TOKEN required\");\n// auth probe\nclient.list_serving_endpoints().await.map_err(|e| format!(\"databricks auth probe failed: {e}\"))?;","typeGuard":null,"tryCatchPattern":"match fetch_v2_models_with_policy(...).await {\n    Err(e @ AgentError::LlmAuth(msg)) => { /* refresh token / fix permissions; msg names both catalog errors */ },\n    Err(e @ AgentError::Llm(msg)) => { /* connectivity or API-shape issue; check network and SDK version */ },\n    Ok(models) => use(models),\n}","preventionTips":["Refresh Databricks tokens on a schedule before they expire.","Verify the service principal can list both serving endpoints and Unity Catalog models.","Probe the workspace API at startup and fail fast with a clear auth message.","Check corporate proxy/egress rules for Databricks workspace hosts."],"tags":["rust","databricks","llm","auth","api-discovery"],"backgroundTag":"databricks-model-discovery-failed","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}