Skip to content

Commit 274705b

Browse files
committed
[core] Fix AssetCheckKey.from_user_string for asset keys containing colons
AssetCheckKey.to_user_string() renders a check key as "<asset_key>:<check_name>", but from_user_string() split on every colon and unpacked into exactly two values. Asset keys can legitimately contain colons (for example the dagster-looker integration emits keys such as ["my_model::my_explore"]), so such a key raised "ValueError: too many values to unpack (expected 2)" when parsed back. This surfaces in the freshness-check sensor, which stores a check key via to_user_string() as its cursor and reads it back with from_user_string() on the next tick; a colon-containing asset key makes every subsequent tick fail. Split off only the trailing ":<name>" segment with rsplit(":", 1). The check name is a plain identifier, so the last segment is unambiguous, and colon-free keys are parsed exactly as before.
1 parent b548e05 commit 274705b

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

python_modules/dagster/dagster/_core/definitions/asset_key.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,11 @@ def to_user_string(self) -> str:
230230

231231
@staticmethod
232232
def from_user_string(user_string: str) -> "AssetCheckKey":
233-
asset_key_str, name = user_string.split(":")
233+
# to_user_string() appends ":<name>" to the asset key's user string, and asset keys
234+
# can themselves contain colons (e.g. dagster-looker emits keys like
235+
# ["my_model::my_explore"]). Split off only the final segment so the asset key portion
236+
# is preserved.
237+
asset_key_str, name = user_string.rsplit(":", 1)
234238
return AssetCheckKey(AssetKey.from_user_string(asset_key_str), name)
235239

236240
@staticmethod

python_modules/dagster/dagster_tests/definitions_tests/test_entity_key.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ def test_asset_job_key_user_string_roundtrip() -> None:
5050
assert AssetJobKey.from_user_string("my_job") == key
5151

5252

53+
@pytest.mark.parametrize(
54+
"check_key",
55+
[
56+
dg.AssetCheckKey(dg.AssetKey("a"), "b"),
57+
dg.AssetCheckKey(dg.AssetKey(["prefix", "asset1"]), "freshness_check"),
58+
# Asset keys can contain colons. For example the dagster-looker integration emits
59+
# keys such as AssetKey(["my_model::my_explore"]). The check name is a plain
60+
# identifier, so the trailing ":<name>" segment is unambiguous.
61+
dg.AssetCheckKey(dg.AssetKey(["my_model::my_explore"]), "freshness_check"),
62+
dg.AssetCheckKey(dg.AssetKey(["snowflake", "db:schema:table"]), "row_count"),
63+
],
64+
)
65+
def test_asset_check_key_user_string_roundtrip(check_key: AssetCheckKey) -> None:
66+
assert AssetCheckKey.from_user_string(check_key.to_user_string()) == check_key
67+
68+
5369
def test_asset_job_key_from_db_string_returns_none_for_non_matching() -> None:
5470
assert AssetJobKey.from_db_string('["a"]') is None
5571
assert AssetJobKey.from_db_string('{"asset_key": "[\\"a\\"]", "check_name": "b"}') is None

0 commit comments

Comments
 (0)