fix(cli): report config source for invalid Git URLs

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
John Kennedy
2026-08-19 23:57:21 +00:00
co-authored by open-swe[bot] <open-swe@users.noreply.github.com>
parent 62ecd5414e
commit 0cce2d2f2b
2 changed files with 32 additions and 5 deletions
+10 -5
View File
@@ -381,7 +381,9 @@ def _get_source_kind(config: Config) -> str | None:
return kind if isinstance(kind, str) else None
def validate_config(config: Config) -> Config:
def validate_config(
config: Config, *, source_path: pathlib.Path | None = None
) -> Config:
"""Validate a configuration dictionary."""
graphs = config.get("graphs", {})
@@ -477,9 +479,12 @@ def validate_config(config: Config) -> Config:
)
_validate_git_http_url_userinfo(
dependency
for dependency in config["dependencies"]
if isinstance(dependency, str)
(
dependency
for dependency in config["dependencies"]
if isinstance(dependency, str)
),
source=source_path,
)
source = config.get("source")
@@ -676,7 +681,7 @@ def validate_config_file(config_path: pathlib.Path) -> Config:
"""Load and validate a configuration file."""
with open(config_path) as f:
config = json.load(f)
validated = validate_config(config)
validated = validate_config(config, source_path=config_path.resolve())
# Enforce the package.json doesn't enforce an
# incompatible Node.js version
if validated.get("node_version"):
+22
View File
@@ -280,6 +280,28 @@ def test_validate_config_rejects_git_http_url_userinfo(dependency: str):
assert "secret%2Ftoken" not in message
def test_validate_config_file_reports_source_for_git_http_url_userinfo(
tmp_path: pathlib.Path,
):
config_path = tmp_path / "langgraph.json"
config_path.write_text(
json.dumps(
{
"python_version": "3.11",
"dependencies": ["git+https://secret-token@github.com/org/private.git"],
"graphs": {"agent": "./agent.py:graph"},
}
)
)
with pytest.raises(click.UsageError) as exc_info:
validate_config_file(config_path)
message = str(exc_info.value)
assert "secret-token" not in message
assert f"Found in: {config_path.resolve()}" in message
@pytest.mark.parametrize(
"manifest", ["package.json", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"]
)