{"record":{"id":"f96de36f3e97bc99","repo":"cube-js/cube","slug":"api-url-is-empty","errorCode":null,"errorMessage":"API URL is empty","messagePattern":"API URL is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust/cube-cli/src/client.rs","lineNumber":250,"sourceCode":"/// recovery note that closes the same comment block is the only part that becomes LIVE,\n/// since it is what a reader arrives at from the failure.\nfn explains(value: &Value) -> Option<String> {\n    if says_nothing(value) {\n        return None;\n    }\n\n    match value {\n        Value::String(said) => Some(said.to_string()),\n        Value::Object(_) | Value::Array(_) => Some(value.to_string()),\n        _ => None,\n    }\n}\n\nimpl Client {\n    fn build(base_url: &str, token: &str, refresh: Option<RefreshAuth>) -> Result<Self> {\n        let base_url = base_url.trim_end_matches('/').to_string();\n        if base_url.is_empty() {\n            bail!(\"API URL is empty\");\n        }\n        Ok(Self {\n            http: reqwest::Client::builder()\n                .user_agent(concat!(\"cube-cli/\", env!(\"CUBE_CLI_VERSION\")))\n                .build()?,\n            base_url,\n            token: Mutex::new(token.to_string()),\n            refresh,\n        })\n    }\n\n    pub fn new(base_url: &str, token: &str) -> Result<Self> {\n        Self::build(base_url, token, None)\n    }\n\n    /// Construct a client that can auto-refresh its access token. When\n    /// `context_name` is set, refreshed tokens are written back to that\n    /// config context.","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube-cli/src/client.rs#L232-L268","documentation":"cube-cli's Client::build validates the base API URL before constructing the HTTP client. If the URL is empty (after trimming trailing slashes), it returns the error 'API URL is empty' rather than making requests to a malformed endpoint.","triggerScenarios":"Running any CLI command when no API URL has been configured: missing --api-url flag, empty CUBE_API_URL env var, or a context in the CLI config whose url field is empty.","commonSituations":"Fresh install without `cube login`; CI environments where the URL env var is unset or set to empty string; a corrupted/blank context entry in the CLI config file.","solutions":["Pass the API URL explicitly: cube <cmd> --api-url https://<cube-deployment>","Run `cube login --name <ctx>` to create a context with a valid URL and switch to it","Set the URL environment variable (e.g. CUBE_API_URL) in your shell/CI before running commands","Inspect the CLI config file and remove/fix contexts with empty url values"],"exampleFix":"// before\nexport CUBE_API_URL=\"\"\ncube data-model get\n// after\nexport CUBE_API_URL=\"https://cube.example.com\"\ncube data-model get","handlingStrategy":"validation","validationCode":"const url = process.env.CUBE_API_URL ?? '';\nif (!url.trim()) { throw new Error('Set CUBE_API_URL or pass --api-url before running cube-cli'); }","typeGuard":"function hasApiUrl(cfg: { apiUrl?: string }): cfg is { apiUrl: string } {\n  return typeof cfg.apiUrl === 'string' && cfg.apiUrl.trim().length > 0;\n}","tryCatchPattern":"try {\n  await runCliCommand();\n} catch (e) {\n  if (/API URL is empty/.test(String(e))) { console.error('Run `cube login --name <ctx>` or set --api-url'); process.exit(2); }\n  throw e;\n}","preventionTips":["Always run `cube login` before first use","Set the API URL env var in CI secrets, and assert it is non-empty in pipeline setup","Never set the URL variable to empty string to 'disable' it — unset it or fix it","Validate context configs contain non-empty url fields"],"tags":["cli","configuration","validation","url"],"backgroundTag":"missing-api-url","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}