Skip to content

Commit b798b2e

Browse files
committed
fix: error when invalidating a nonexistent environment
sqlmesh invalidate ENVIRONMENT reported success even when the environment did not exist, so a mistyped name looked like it worked. Check the environment exists first and raise a clear error (nonzero exit) otherwise. Fixes #5621 Signed-off-by: Nishchay Mahor <nishchaymahor@gmail.com>
1 parent 909ee91 commit b798b2e

2 files changed

Lines changed: 16 additions & 0 deletions

File tree

sqlmesh/core/context.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,8 @@ def invalidate_environment(self, name: str, sync: bool = False) -> None:
18791879
be deleted asynchronously by the janitor process.
18801880
"""
18811881
name = Environment.sanitize_name(name)
1882+
if self.state_sync.get_environment(name) is None:
1883+
raise SQLMeshError(f"Environment '{name}' does not exist.")
18821884
self.state_sync.invalidate_environment(name)
18831885
if sync:
18841886
self._cleanup_environments(name=name)

tests/core/test_context.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,6 +1928,20 @@ def test_invalidate_environment_no_sync_skips_cleanup(sushi_context, mocker: Moc
19281928
state_sync_mock.delete_expired_environments.assert_not_called()
19291929

19301930

1931+
def test_invalidate_environment_nonexistent_raises(sushi_context, mocker: MockerFixture) -> None:
1932+
"""Invalidating an environment that does not exist should error instead of
1933+
reporting success, so a mistyped name is caught rather than silently accepted."""
1934+
state_sync_mock = mocker.patch.object(
1935+
type(sushi_context), "state_sync", new_callable=mocker.PropertyMock
1936+
).return_value
1937+
state_sync_mock.get_environment.return_value = None
1938+
1939+
with pytest.raises(SQLMeshError, match="Environment 'doesnotexist' does not exist"):
1940+
sushi_context.invalidate_environment("doesnotexist")
1941+
1942+
state_sync_mock.invalidate_environment.assert_not_called()
1943+
1944+
19311945
@pytest.mark.slow
19321946
def test_plan_default_end(sushi_context_pre_scheduling: Context):
19331947
prod_plan_builder = sushi_context_pre_scheduling.plan_builder("prod")

0 commit comments

Comments
 (0)