Repository: PostHog/posthog
Pull request #29440: chore(temporal log sq): Temporal job error handling for mat views
Author: login: phixMe
Created: 2025-03-03T21:55:29Z | Merged: 2025-03-05T21:03:41Z

## Problem

We currently do not handle errors out of materialization really at all and surface issues back to users, or us for debugging. 

## Changes

- [x] Handlers for some error types that we see
- [x] Migration for new error type 
- [x] UI presentation 

## Does this work well for both Cloud and self-hosted?
Yes

## How did you test this code?
I can't really generate these errors in local dev because they are for huge tables that push our limits.



Diff:
diff --git a/frontend/__snapshots__/scenes-app-insights--stickiness--dark--webkit.png b/frontend/__snapshots__/scenes-app-insights--stickiness--dark--webkit.png
index 5eefb893657f..f20f5d519ada 100644
Binary files a/frontend/__snapshots__/scenes-app-insights--stickiness--dark--webkit.png and b/frontend/__snapshots__/scenes-app-insights--stickiness--dark--webkit.png differ
diff --git a/frontend/__snapshots__/scenes-app-insights--stickiness--light--webkit.png b/frontend/__snapshots__/scenes-app-insights--stickiness--light--webkit.png
index ad26853dae0a..cccfd1cd2933 100644
Binary files a/frontend/__snapshots__/scenes-app-insights--stickiness--light--webkit.png and b/frontend/__snapshots__/scenes-app-insights--stickiness--light--webkit.png differ
diff --git a/frontend/__snapshots__/web-analytics-tiles--browser--dark.png b/frontend/__snapshots__/web-analytics-tiles--browser--dark.png
index 0b4d59e82eaa..2b155c88b64e 100644
Binary files a/frontend/__snapshots__/web-analytics-tiles--browser--dark.png and b/frontend/__snapshots__/web-analytics-tiles--browser--dark.png differ
diff --git a/frontend/__snapshots__/web-analytics-tiles--browser--light.png b/frontend/__snapshots__/web-analytics-tiles--browser--light.png
index 4767eec6c86e..205dc46e8790 100644
Binary files a/frontend/__snapshots__/web-analytics-tiles--browser--light.png and b/frontend/__snapshots__/web-analytics-tiles--browser--light.png differ
diff --git a/frontend/src/scenes/data-warehouse/editor/OutputPaneTabs/InfoTab.tsx b/frontend/src/scenes/data-warehouse/editor/OutputPaneTabs/InfoTab.tsx
index 8a2b35cb1add..dda841cff7ba 100644
--- a/frontend/src/scenes/data-warehouse/editor/OutputPaneTabs/InfoTab.tsx
+++ b/frontend/src/scenes/data-warehouse/editor/OutputPaneTabs/InfoTab.tsx
@@ -71,6 +71,11 @@ export function InfoTab({ codeEditorKey }: InfoTabProps): JSX.Element {
                     <div className="flex flex-row items-center gap-2">
                         <h3 className="mb-0">Materialization</h3>
                         <LemonTag type="warning">BETA</LemonTag>
+                        {savedQuery?.latest_error && savedQuery.status === 'Failed' && (
+                            <Tooltip title={savedQuery.latest_error}>
+                                <LemonTag type="danger">Error</LemonTag>
+                            </Tooltip>
+                        )}
                     </div>
                     <div>
                         {savedQuery?.sync_frequency || savedQuery?.last_run_at ? (
diff --git a/frontend/src/types.ts b/frontend/src/types.ts
index 3199fa4569db..85153161eaad 100644
--- a/frontend/src/types.ts
+++ b/frontend/src/types.ts
@@ -4179,6 +4179,7 @@ export interface DataWarehouseSavedQuery {
     last_run_at?: string
     sync_frequency: string
     status?: string
+    latest_error: string | null
 }
 
 export interface DataWarehouseViewLink {
diff --git a/posthog/demo/products/hedgebox/matrix.py b/posthog/demo/products/hedgebox/matrix.py
index 363561ebbbda..546472bdae2f 100644
--- a/posthog/demo/products/hedgebox/matrix.py
+++ b/posthog/demo/products/hedgebox/matrix.py
@@ -73,7 +73,7 @@ def __init__(self, *args, **kwargs):
         self._business_account = None
 
     def __str__(self) -> str:
-        return self.company.name if self.company else f"Social Circle #{self.index+1}"
+        return self.company.name if self.company else f"Social Circle #{self.index + 1}"
 
     def radius_distribution(self) -> float:
         return self.random.betavariate(1.5, 5)
diff --git a/posthog/migrations/0682_datawarehousesavedquery_latest_error.py b/posthog/migrations/0682_datawarehousesavedquery_latest_error.py
new file mode 100644
index 000000000000..e25876a6f549
--- /dev/null
+++ b/posthog/migrations/0682_datawarehousesavedquery_latest_error.py
@@ -0,0 +1,17 @@
+# Generated by Django 4.2.18 on 2025-03-03 21:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("posthog", "0681_file_system_depth"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="datawarehousesavedquery",
+            name="latest_error",
+            field=models.TextField(blank=True, default=None, null=True),
+        ),
+    ]
diff --git a/posthog/migrations/max_migration.txt b/posthog/migrations/max_migration.txt
index 9bc6fad4dadd..35805b25e2fe 100644
--- a/posthog/migrations/max_migration.txt
+++ b/posthog/migrations/max_migration.txt
@@ -1 +1 @@
-0681_file_system_depth
+0682_datawarehousesavedquery_latest_error
\ No newline at end of file
diff --git a/posthog/session_recordings/test/__snapshots__/test_session_recordings.ambr b/posthog/session_recordings/test/__snapshots__/test_session_recordings.ambr
index c748b294a1c0..f404ea6b2cf0 100644
--- a/posthog/session_recordings/test/__snapshots__/test_session_recordings.ambr
+++ b/posthog/session_recordings/test/__snapshots__/test_session_recordings.ambr
@@ -818,6 +818,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -1891,6 +1892,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -2510,6 +2512,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -3128,6 +3131,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -3823,6 +3827,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -4495,6 +4500,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -4793,6 +4799,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -5400,6 +5407,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -6025,6 +6033,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -6594,6 +6603,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -6630,6 +6640,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
@@ -7277,6 +7288,7 @@
          "posthog_datawarehousesavedquery"."id",
          "posthog_datawarehousesavedquery"."name",
          "posthog_datawarehousesavedquery"."team_id",
+         "posthog_datawarehousesavedquery"."latest_error",
          "posthog_datawarehousesavedquery"."columns",
          "posthog_datawarehousesavedquery"."external_tables",
          "posthog_datawarehousesavedquery"."query",
diff --git a/posthog/temporal/data_modeling/run_workflow.py b/posthog/temporal/data_modeling/run_workflow.py
index 86ec130c423c..59cd7b6e13db 100644
--- a/posthog/temporal/data_modeling/run_workflow.py
+++ b/posthog/temporal/data_modeling/run_workflow.py
@@ -125,6 +125,7 @@ class QueueMessage:
 
     status: ModelStatus
     label: str
+    error: str | None = None
 
 
 Results = collections.namedtuple("Results", ("completed", "failed", "ancestor_failed"))
@@ -247,6 +248,18 @@ async def put_models_in_queue(models: collections.abc.Iterable[ModelNode], queue
             tg.create_task(queue.put(QueueMessage(status=ModelStatus.READY, label=model.label)))
 
 
+class CHQueryErrorMemoryLimitExceeded(Exception):
+    """Exception raised when a ClickHouse query exceeds memory limits."""
+
+    pass
+
+
+class CannotCoerceColumnException(Exception):
+    """Exception raised when column types cannot be coerced."""
+
+    pass
+
+
 async def handle_model_ready(model: ModelNode, team_id: int, queue: asyncio.Queue[QueueMessage]) -> None:
     """Handle a model that is ready to run by materializing.
 
@@ -263,9 +276,15 @@ async def handle_model_ready(model: ModelNode, team_id: int, queue: asyncio.Queu
         if model.selected is True:
             team = await database_sync_to_async(Team.objects.get)(id=team_id)
             await materialize_model(model.label, team)
+    except CHQueryErrorMemoryLimitExceeded as err:
+        await logger.aexception("Memory limit exceeded for model %s: %s", model.label, str(err))
+        await queue.put(QueueMessage(status=ModelStatus.FAILED, label=model.label, error=str(err)))
+    except CannotCoerceColumnException as err:
+        await logger.aexception("Type coercion error for model %s: %s", model.label, str(err))
+        await queue.put(QueueMessage(status=ModelStatus.FAILED, label=model.label, error=str(err)))
     except Exception as err:
         await logger.aexception("Failed to materialize model %s due to error: %s", model.label, str(err))
-        await queue.put(QueueMessage(status=ModelStatus.FAILED, label=model.label))
+        await queue.put(QueueMessage(status=ModelStatus.FAILED, label=model.label, error=str(err)))
     else:
         await logger.ainfo("Materialized model %s", model.label)
         await queue.put(QueueMessage(status=ModelStatus.COMPLETED, label=model.label))
@@ -327,7 +346,22 @@ async def materialize_model(model_label: str, team: Team) -> tuple[str, DeltaTab
         destination=destination,
         dataset_name=f"team_{team.pk}_model_{model_label}",
     )
-    _ = await asyncio.to_thread(pipeline.run, hogql_table(hogql_query, team, saved_query.name, table_columns))
+
+    try:
+        _ = await asyncio.to_thread(pipeline.run, hogql_table(hogql_query, team, saved_query.name, table_columns))
+    except Exception as e:
+        error_message = str(e)
+        if "Query exceeds memory limits" in error_message:
+            saved_query.latest_error = error_message
+            await database_sync_to_async(saved_query.save)()
+            raise CHQueryErrorMemoryLimitExceeded(
+                f"Query for model {model_label} exceeds memory limits. Try reducing its scope by changing the time range."
+            ) from e
+
+        elif "Cannot coerce type" in error_message:
+            saved_query.latest_error = error_message
+            await database_sync_to_async(saved_query.save)()
+            raise CannotCoerceColumnException(f"Type coercion error in model {model_label}: {error_message}") from e
 
     tables = get_delta_tables(pipeline)
 
diff --git a/posthog/warehouse/api/saved_query.py b/posthog/warehouse/api/saved_query.py
index 5ec815082211..20618a84d092 100644
--- a/posthog/warehouse/api/saved_query.py
+++ b/posthog/warehouse/api/saved_query.py
@@ -59,8 +59,9 @@ class Meta:
             "columns",
             "status",
             "last_run_at",
+            "latest_error",
         ]
-        read_only_fields = ["id", "created_by", "created_at", "columns", "status", "last_run_at"]
+        read_only_fields = ["id", "created_by", "created_at", "columns", "status", "last_run_at", "latest_error"]
 
     def get_columns(self, view: DataWarehouseSavedQuery) -> list[SerializedField]:
         team_id = self.context["team_id"]
diff --git a/posthog/warehouse/models/datawarehouse_saved_query.py b/posthog/warehouse/models/datawarehouse_saved_query.py
index 426f50bfbdc0..2a7f87d834fe 100644
--- a/posthog/warehouse/models/datawarehouse_saved_query.py
+++ b/posthog/warehouse/models/datawarehouse_saved_query.py
@@ -55,6 +55,7 @@ class Status(models.TextChoices):
 
     name = models.CharField(max_length=128, validators=[validate_saved_query_name])
     team = models.ForeignKey(Team, on_delete=models.CASCADE)
+    latest_error = models.TextField(default=None, null=True, blank=True)
     columns = models.JSONField(
         default=dict,
         null=True,


Reviews:
user: login: greptile-apps[bot]
body: 
## PR Summary

This PR adds error handling and user feedback for materialization processes in data warehouse saved queries, focusing on surfacing issues during large table operations.

- Added `latest_error` TextField to `DataWarehouseSavedQuery` model via migration 0680 for storing materialization failure messages
- Implemented specific error handling in `run_workflow.py` for memory limit and type coercion issues during materialization
- Added error display UI in `InfoTab.tsx` with tooltips showing materialization failure messages
- Enhanced `QueueMessage` class with error field for propagating specific error types through the workflow

<sub>7 file(s) reviewed, 2 comment(s)</sub>
<sub>[Edit PR Review Bot Settings](https://app.greptile.com/review/github) | [Greptile](https://greptile.com?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=posthog_29440)</sub>
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T22:09:42Z
user: login: Gilbert09
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-04T09:07:13Z

Review comments:
diff_hunk: @@ -0,0 +1,17 @@
+# Generated by Django 4.2.18 on 2025-03-03 21:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("posthog", "0679_feature_flag_concurrency"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="datawarehousesavedquery",
+            name="latest_error",
+            field=models.TextField(blank=True, default=None, null=True),
path: posthog/migrations/0680_datawarehousesavedquery_latest_error.py
user: login: greptile-apps[bot]
body: style: Consider setting default='' instead of default=None since blank=True is used. This would be more consistent with Django's handling of empty text fields.
created_at: 2025-03-03T22:05:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -327,7 +346,22 @@ async def materialize_model(model_label: str, team: Team) -> tuple[str, DeltaTab
         destination=destination,
         dataset_name=f"team_{team.pk}_model_{model_label}",
     )
-    _ = await asyncio.to_thread(pipeline.run, hogql_table(hogql_query, team, saved_query.name, table_columns))
+
+    try:
+        _ = await asyncio.to_thread(pipeline.run, hogql_table(hogql_query, team, saved_query.name, table_columns))
+    except Exception as e:
+        error_message = str(e)
+        if "Query exceeds memory limits" in error_message:
+            saved_query.latest_error = error_message
+            await database_sync_to_async(saved_query.save)()
+            raise CHQueryErrorMemoryLimitExceeded(
+                f"Query for model {model_label} exceeds memory limits. Try reducing its scope by changing the time range."
+            ) from e
+
+        elif "Cannot coerce type" in error_message:
+            saved_query.latest_error = error_message
+            await database_sync_to_async(saved_query.save)()
+            raise CannotCoerceColumnException(f"Type coercion error in model {model_label}: {error_message}") from e
path: posthog/temporal/data_modeling/run_workflow.py
user: login: greptile-apps[bot]
body: style: Consider re-raising other exceptions with saved_query.latest_error set to maintain consistent error state
created_at: 2025-03-03T22:07:08Z
author_association: CONTRIBUTOR

PR comments:
user: login: posthog-bot
created_at: 2025-03-03T22:16:35Z
body: ## 📸 UI snapshots have been updated

**1** snapshot changes in total. **0** added, **1** modified, **0** deleted:

- **`chromium`**: **0** added, **1** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/1a5be1b693873c3686d601e7941f3adbc0374b5e))
- `webkit`: **0** added, **0** modified, **0** deleted

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/724127565de7832d12c534fcac0627c6be48c8c7).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-03T22:17:46Z
body: **Size Change:** 0 B 

**Total Size:** 9.92 MB



<details><summary>ℹ️ <strong>View Unchanged</strong></summary>

| Filename | Size |
| :--- | :---: |
| `frontend/dist/toolbar.js` | 9.92 MB |

</details>



<a href="https://github.com/preactjs/compressed-size-action"><sub>compressed-size-action</sub></a>
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T16:38:05Z
body: ## 📸 UI snapshots have been updated

**2** snapshot changes in total. **0** added, **2** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **2** modified, **0** deleted (wasn't pushed!)

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/74d6ed89d34dadd9ae5cf9922343aba5cb9c812b).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T16:57:53Z
body: ## 📸 UI snapshots have been updated

**2** snapshot changes in total. **0** added, **2** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **2** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/4d6560c6bf4354b76e0c8c6cdd0c9fc441d49cd7))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/b2ee97547b91d7d10d0b7e7b0aca43800a75aa56).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T17:17:23Z
body: ## 📸 UI snapshots have been updated

**2** snapshot changes in total. **0** added, **2** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **2** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/bff63cf3e91447e636eab1d254264dd6fc00ea33))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/066fdeaacb67f60409bf084d29dfa95d1ac68ae1).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T17:56:48Z
body: ## 📸 UI snapshots have been updated

**2** snapshot changes in total. **0** added, **2** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **2** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/eb31f01cdf08b9b58a4a44749ec2aa66d51d842d))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/5bc0f6eca7d93f268d2c385b0fce2a7d0a444dad).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T18:16:36Z
body: ## 📸 UI snapshots have been updated

**6** snapshot changes in total. **0** added, **6** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **6** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/758fc846af1f8e6f7c38c3ea2205aa745046c064))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/bba138469b474d62bd0c636d4b8f10e44067ad30).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T18:36:21Z
body: ## 📸 UI snapshots have been updated

**4** snapshot changes in total. **0** added, **4** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **4** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/e8641f22534a9888929c54b22b0bd9e0b8c02be4))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/89db44fea950b10805460c782af54af240b43507).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T19:44:56Z
body: ## 📸 UI snapshots have been updated

**4** snapshot changes in total. **0** added, **4** modified, **0** deleted:

- **`chromium`**: **0** added, **2** modified, **0** deleted ([diff for shard 1](https://github.com/PostHog/posthog/pull/29440/commits/717c65faeb04b164d67dc4aebba4d61d099fc05c))
- **`webkit`**: **0** added, **2** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/29466a841e2a3c87c7984c38ead30a667334c51a))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/5927d16c70cdfd8b7475b43911c89c5783c2d01b).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T20:04:13Z
body: ## 📸 UI snapshots have been updated

**4** snapshot changes in total. **0** added, **4** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **4** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/2e4db856023d4dfe96bb636ec06c0d4df6434744))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/45abac7edba002fa6997c92c268b06a606eb0298).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T20:23:51Z
body: ## 📸 UI snapshots have been updated

**4** snapshot changes in total. **0** added, **4** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **4** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/f1fef3327b7487314a2d52ae934864f0a3edc060))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/b5a65454bc9b5c612365fa3b5685945ded9a4479).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR
user: login: posthog-bot
created_at: 2025-03-05T20:43:27Z
body: ## 📸 UI snapshots have been updated

**2** snapshot changes in total. **0** added, **2** modified, **0** deleted:

- `chromium`: **0** added, **0** modified, **0** deleted
- **`webkit`**: **0** added, **2** modified, **0** deleted ([diff for shard 2](https://github.com/PostHog/posthog/pull/29440/commits/32aaa77100c1661c9903123b443694ff790fac72))

Triggered by [this commit](https://github.com/PostHog/posthog/pull/29440/commits/bb7dd21e82c3a69914000a79e7df74af96bfc142).

👉 **[Review this PR's diff of snapshots.](https://github.com/PostHog/posthog/pull/29440/files#:~:text=frontend/__snapshots__/)**
author_association: CONTRIBUTOR