Body
The UI endpoints that return asset_expression declare it as dict | None on the Python datamodel — datamodels/dags.py, datamodels/ui/dags.py, datamodels/ui/assets.py, datamodels/ui/partitioned_dag_runs.py. OpenAPI gen turns this into { [k: string]: unknown } | null in the generated TypeScript, so the UI hand-writes an ExpressionType discriminated union in src/components/AssetExpression/ and the consumers (AssetProgressCell.tsx, pages/DagsList/AssetSchedule.tsx) cast unknown as ExpressionType with no runtime check.
If the server-side shape ever changes the TypeScript build won't catch it — the failure mode is a blank render or a discriminator-missing crash at runtime.
from #64571 (comment)
Committer
Body
The UI endpoints that return
asset_expressiondeclare it asdict | Noneon the Python datamodel —datamodels/dags.py,datamodels/ui/dags.py,datamodels/ui/assets.py,datamodels/ui/partitioned_dag_runs.py. OpenAPI gen turns this into{ [k: string]: unknown } | nullin the generated TypeScript, so the UI hand-writes an ExpressionType discriminated union insrc/components/AssetExpression/and the consumers (AssetProgressCell.tsx,pages/DagsList/AssetSchedule.tsx) cast unknown asExpressionTypewith no runtime check.If the server-side shape ever changes the TypeScript build won't catch it — the failure mode is a blank render or a discriminator-missing crash at runtime.
from #64571 (comment)
Committer