This is an automated email from the ASF dual-hosted git repository.

kevinjqliu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git


The following commit(s) were added to refs/heads/main by this push:
     new 09de7900 fix: show helpful error when hive catalog config is missing 
uri (#3077)
09de7900 is described below

commit 09de79000f6b59fc36667a6e8e1ccb62ad554244
Author: jj.lee <[email protected]>
AuthorDate: Mon Feb 23 07:54:39 2026 +0900

    fix: show helpful error when hive catalog config is missing uri (#3077)
    
    Closes #3069
    
      # Rationale for this change
    
    When a catalog is explicitly configured with `type: hive` but `uri` is
    missing in `.pyiceberg.yaml`,
    the CLI currently fails with a raw `KeyError('uri')`, which is surfaced
    as just:
    
      `'uri'`
    
    ```bash
    ❯ cat .pyiceberg.yaml
    catalog:
      my_hive_catalog:
        type: hive
        warehouse: warehouse_loc
    ❯ uv run pyiceberg --catalog my_hive_catalog list
    'uri'
    ```
    
    It's confusing for users because the command appears to return an
    identifier-like value instead of
      a configuration error.
    
    This change adds explicit validation for required catalog properties
    when the catalog type is already
    specified (e.g. `hive`, `rest`, `sql`), so users get a clear actionable
    error message instead.
    
      ## Are these changes tested?
    
      Yes.
    
    - Added a CLI regression test for `--catalog <name> list` with `type:
    hive` and missing `uri`
    - Verified the error output contains a helpful `URI missing...` message
    and no longer prints `'uri'`
    
      ## Are there any user-facing changes?
    
      Yes.
    
      Users now see a clear error message (for example):
    
    `URI missing, please provide using --uri, the config or environment
    variable PYICEBERG_CATALOG__<CATALOG_NAME>__URI`
    
    instead of a raw `'uri'` error when `type: hive` is configured without
    `uri`.
---
 pyiceberg/catalog/__init__.py |  9 +++++++++
 tests/cli/test_console.py     | 13 +++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/pyiceberg/catalog/__init__.py b/pyiceberg/catalog/__init__.py
index b4ca9a2e..8628f6b6 100644
--- a/pyiceberg/catalog/__init__.py
+++ b/pyiceberg/catalog/__init__.py
@@ -218,6 +218,14 @@ def infer_catalog_type(name: str, catalog_properties: 
RecursiveDict) -> CatalogT
     )
 
 
+def _check_required_catalog_properties(name: str, catalog_type: CatalogType, 
conf: RecursiveDict) -> None:
+    """Validate required properties for explicitly selected catalog types."""
+    if catalog_type in {CatalogType.REST, CatalogType.HIVE, CatalogType.SQL} 
and URI not in conf:
+        raise ValueError(
+            f"URI missing, please provide using --uri, the config or 
environment variable PYICEBERG_CATALOG__{name.upper()}__URI"
+        )
+
+
 def load_catalog(name: str | None = None, **properties: str | None) -> Catalog:
     """Load the catalog based on the properties.
 
@@ -263,6 +271,7 @@ def load_catalog(name: str | None = None, **properties: str 
| None) -> Catalog:
         catalog_type = infer_catalog_type(name, conf)
 
     if catalog_type:
+        _check_required_catalog_properties(name, catalog_type, conf)
         return AVAILABLE_CATALOGS[catalog_type](name, cast(dict[str, str], 
conf))
 
     raise ValueError(f"Could not initialize catalog with the following 
properties: {properties}")
diff --git a/tests/cli/test_console.py b/tests/cli/test_console.py
index 0f896dc9..81165e8b 100644
--- a/tests/cli/test_console.py
+++ b/tests/cli/test_console.py
@@ -48,6 +48,19 @@ def test_missing_uri(mocker: MockFixture, 
empty_home_dir_path: str) -> None:
     assert result.output == "Could not initialize catalog with the following 
properties: {}\n"
 
 
+def test_hive_catalog_missing_uri_shows_helpful_error(mocker: MockFixture) -> 
None:
+    mock_env_config = mocker.MagicMock()
+    mock_env_config.get_catalog_config.return_value = {"type": "hive"}
+    mocker.patch("pyiceberg.catalog._ENV_CONFIG", mock_env_config)
+
+    runner = CliRunner()
+    result = runner.invoke(run, ["--catalog", "my_hive_catalog", "list"])
+
+    assert result.exit_code == 1
+    assert "URI missing, please provide using --uri" in result.output
+    assert "'uri'" not in result.output
+
+
 @pytest.fixture(autouse=True)
 def env_vars(mocker: MockFixture) -> None:
     mocker.patch.dict(os.environ, MOCK_ENVIRONMENT)

Reply via email to