247e422eac
## Fixes #20597 ### Problem A person's (or any record's) timeline renders the whole widget as **"Invalid configuration"** when it contains an `*.updated` event without a usable `properties.diff`. The error-boundary fallback (`PageLayoutWidgetInvalidConfigDisplay`) is triggered because `EventRowMainObjectUpdated` **throws** during render: ```ts const diff = event.properties?.diff; // can be undefined const diffEntries = Object.entries(diff); // throws TypeError when undefined if (diffEntries.length === 0) { throw new Error('Cannot render update description without changes'); } ``` `filterOutInvalidTimelineActivities` only validates activities that **already carry** a diff (`canSkipValidation = !diff`), so a main-object `*.updated` event with a missing diff passes straight through to this renderer and crashes it. A single malformed row takes down the entire timeline. ### Fix Render nothing instead of throwing when an update event has no changes to show. This mirrors the sibling `EventRowMainObject` default branch (which returns `null`) and the filter's own behaviour of dropping empty diffs, and keeps one bad row from crashing the whole widget. The fix is intentionally kept in the renderer rather than the filter: the filter cannot distinguish a diff-less main-object update (must be dropped) from a diff-less `linked-task`/`linked-note` update (legitimately has `properties: {}` and renders fine via `EventRowActivity`) without duplicating routing logic. ### Test Added `EventRowMainObjectUpdated.test.tsx` — a regression test asserting the component renders nothing (no throw) for both a missing-diff and an empty-diff update event.