From 0ba30890fe6d2f84a89dab2c2f5ceb9d517f2854 Mon Sep 17 00:00:00 2001 From: Anas Khan <83116240+anxkhn@users.noreply.github.com> Date: Sun, 5 Jul 2026 00:52:21 +0530 Subject: [PATCH] fix(model): raise ConfigError for empty time_column tuple An empty time_column tuple, e.g. `INCREMENTAL_BY_TIME_RANGE (time_column ())`, parsed into an empty exp.Tuple and TimeColumn.create indexed v.expressions[0] without checking, so it surfaced a bare IndexError with no config context instead of the ConfigError already used for the other empty/invalid time_column inputs. Guard the empty tuple and raise the same "Time Column cannot be empty." ConfigError. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com> --- sqlmesh/core/model/kind.py | 2 ++ tests/core/test_model.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/sqlmesh/core/model/kind.py b/sqlmesh/core/model/kind.py index 7ae1ef8c0d..a8960fc3e1 100644 --- a/sqlmesh/core/model/kind.py +++ b/sqlmesh/core/model/kind.py @@ -341,6 +341,8 @@ def to_property(self, dialect: str = "") -> exp.Property: @classmethod def create(cls, v: t.Any, dialect: str) -> Self: if isinstance(v, exp.Tuple): + if not v.expressions: + raise ConfigError("Time Column cannot be empty.") column_expr = v.expressions[0] column = ( exp.column(column_expr) if isinstance(column_expr, exp.Identifier) else column_expr diff --git a/tests/core/test_model.py b/tests/core/test_model.py index 38453691df..6f286e309d 100644 --- a/tests/core/test_model.py +++ b/tests/core/test_model.py @@ -2680,6 +2680,21 @@ def test_time_column(): assert model.time_column.format == "%Y-%m" assert model.time_column.expression == d.parse_one("(\"ds\", '%Y-%m')") + expressions = d.parse( + """ + MODEL ( + name db.table, + kind INCREMENTAL_BY_TIME_RANGE( + time_column () + ) + ); + + SELECT col::text, ds::text + """ + ) + with pytest.raises(ConfigError, match="Time Column cannot be empty."): + load_sql_based_model(expressions) + def test_default_time_column(): expressions = d.parse(