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

cgivre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/drill-mcp.git

commit 0322cf06b5d060c40ebcb5ea1adb6ee7086f71f0
Author: cgivre <[email protected]>
AuthorDate: Wed Aug 12 16:27:38 2026 -0400

    fix: drop pydantic's input_value from ConfigError messages
    
    ConfigError(str(exc)) on a pydantic ValidationError embeds
    input_value=... for every error -- e.g. an unquoted `password: 12345`
    in a YAML config produces "input_value=12345" verbatim, which main()
    prints to stderr and any log capturing it. Build the message from
    exc.errors()'s loc/msg fields only, dropping the input value.
---
 drill_mcp/config.py  | 11 ++++++++++-
 tests/test_config.py | 11 +++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drill_mcp/config.py b/drill_mcp/config.py
index f413765..721310a 100644
--- a/drill_mcp/config.py
+++ b/drill_mcp/config.py
@@ -112,4 +112,13 @@ def load_config(
     try:
         return Config(**values)
     except ValidationError as exc:
-        raise ConfigError(str(exc)) from exc
+        # `str(exc)` embeds pydantic's `input_value=...` for every error,
+        # which echoes the offending config value verbatim -- including a
+        # password typed unquoted in YAML (e.g. `password: 12345`, which
+        # pydantic reports as `input_value=12345`). That must never reach
+        # stderr or a log. Rebuild the message from `loc`/`msg` only.
+        details = "; ".join(
+            f"{'.'.join(str(p) for p in err['loc'])}: {err['msg']}" if 
err["loc"] else err["msg"]
+            for err in exc.errors()
+        )
+        raise ConfigError(details) from exc
diff --git a/tests/test_config.py b/tests/test_config.py
index e7c1931..a40e59d 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -107,3 +107,14 @@ def test_config_is_immutable():
     cfg = load_config(env={})
     with pytest.raises(ValidationError, match="frozen"):
         cfg.url = "http://elsewhere:8047";
+
+
+def test_a_non_string_password_does_not_appear_in_the_error_message():
+    # pydantic's default ValidationError text embeds `input_value=...` for
+    # every error -- e.g. an unquoted `password: 12345` in YAML produces
+    # "input_value=12345" verbatim. ConfigError must not echo that: `main()`
+    # prints it to stderr, and any log capturing stderr would then carry the
+    # (would-be) password in plaintext.
+    with pytest.raises(ConfigError) as exc:
+        load_config(env={}, overrides={"password": 12345})
+    assert "12345" not in str(exc.value)

Reply via email to