From e42ab5d5890498762d51b8ee2e60b7d2596bff2a Mon Sep 17 00:00:00 2001 From: Hugo Durand Date: Tue, 22 Sep 2026 16:05:15 -0400 Subject: [PATCH] fix(cli): point a managed build at --push-to in a listener workspace --- libs/cli/langgraph_cli/deploy.py | 33 +++++++++++++------ .../unit_tests/cli/test_deploy_command.py | 15 +++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/libs/cli/langgraph_cli/deploy.py b/libs/cli/langgraph_cli/deploy.py index 7b6a82e5b..4020549e1 100644 --- a/libs/cli/langgraph_cli/deploy.py +++ b/libs/cli/langgraph_cli/deploy.py @@ -1430,18 +1430,31 @@ def _resolve_or_create( ) if found is not None: return found.id, step - created, step = _create_deployment( - ctx.client, - step, - name=ctx.selector.name, - source=source, - source_config={"deployment_type": ctx.deployment_type}, - source_revision_config={}, - secrets=ctx.secrets, - ) + try: + created, step = _create_deployment( + ctx.client, + step, + name=ctx.selector.name, + source=source, + source_config={"deployment_type": ctx.deployment_type}, + source_revision_config={}, + secrets=ctx.secrets, + ) + except HostBackendError as err: + if _needs_a_listener(err): + raise click.UsageError( + "This workspace deploys through a listener in your own cluster, so " + "the image has to come from a registry you manage. Re-run with " + "--push-to /." + ) from None + raise return created.id, step +def _needs_a_listener(err: HostBackendError) -> bool: + return err.status_code == 400 and _LISTENER_REQUIRED_MARKER in err.message + + def _available_listeners(client: HostBackendClient) -> tuple[Listener, ...]: resources = _call_host_backend_with_optional_tenant( client, lambda c: c.list_listeners() @@ -1573,7 +1586,7 @@ class CustomerRegistrySource: secrets=ctx.secrets, ) except HostBackendError as err: - if err.status_code == 400 and _LISTENER_REQUIRED_MARKER in err.message: + if _needs_a_listener(err): raise click.UsageError( "This workspace deploys through a listener. Re-run with " f"--listener-id and --k8s-namespace.\n{err.message}" diff --git a/libs/cli/tests/unit_tests/cli/test_deploy_command.py b/libs/cli/tests/unit_tests/cli/test_deploy_command.py index 3d54b1c76..bfcf9118b 100644 --- a/libs/cli/tests/unit_tests/cli/test_deploy_command.py +++ b/libs/cli/tests/unit_tests/cli/test_deploy_command.py @@ -932,3 +932,18 @@ def test_a_listener_without_an_id_is_ignored(deploy_project: DeployProject) -> N "listener_id": "listener-1", "listener_config": {"k8s_namespace": "agents"}, } + + +def test_a_managed_build_in_a_listener_workspace_points_at_push_to( + deploy_project: DeployProject, +) -> None: + deploy_project.control_plane.create_error = ( + "Source configuration error: 'source_config.listener_id' is required " + "for workspace with available listener IDs: ['listener-1']" + ) + + result = deploy_project.run("--no-remote") + + assert result.exit_code != 0 + assert "--push-to" in result.output + assert deploy_project.docker.verbs() == []