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)
