Skip to content

fix: prevent frozen format from crashing CustomMetricModal on reopen#22065

Open
charliedowler wants to merge 1 commit intomainfrom
repro-fix/custom-metric-modal-frozen-format
Open

fix: prevent frozen format from crashing CustomMetricModal on reopen#22065
charliedowler wants to merge 1 commit intomainfrom
repro-fix/custom-metric-modal-frozen-format

Conversation

@charliedowler
Copy link
Copy Markdown
Contributor

Bug

When a user creates or edits a custom metric in the Explorer's CustomMetricModal and then reopens it to change the format type, React throws:

TypeError: Cannot assign to read only property 'type' of object '#<Object>'

This crashes the modal via the ErrorBoundary. Sentry: LIGHTDASH-FRONTEND-G3 / Linear: PROD-2067.

Expected

The format type selector in CustomMetricModal works correctly across multiple open/close cycles.

Root cause

CustomMetricModal/index.tsx passes form.values.format by reference as formatOptions: format to prepareCustomMetricData. The returned metric is dispatched to Redux, and Redux Toolkit (Immer) deep-freezes the action payload in-place — which, through the shared reference, also freezes the form's internal format object.

On the next modal open, when the user changes the format type, @mantine/form calls klona(values) internally (via setFieldValue). klona/full preserves non-writable property descriptors from frozen objects. The subsequent cloned.format.type = newValue assignment then throws TypeError: Cannot assign to read only property 'type' in strict mode (all ESM/React code runs strict).

This is identical to the bug fixed in FormatModal (see FormatModal/index.tsx:46-49).

Reproduction

Failing test: packages/frontend/src/components/Explorer/CustomMetricModal/utils/index.test.ts

The third test (format passed to prepareCustomMetricData is isolated from Immer freeze) passes format by reference (simulating the buggy modal code), deep-freezes the result (simulating Immer dispatch), and asserts the original format is not frozen. This assertion fails — proving the reference chain propagates the freeze.

Evidence (before)

  • Failing test output:
    AssertionError: expected true to be false
    ❯ expect(Object.isFrozen(format)).toBe(false)
    
    format IS frozen (true) when it should not be (false).

Fix

Pending — see follow-up commit.

Failing test demonstrating that form.values.format is frozen in-place
when passed by reference to prepareCustomMetricData and the returned
metric is deep-frozen by Immer (Redux Toolkit). On the next modal open,
@mantine/form's klona-based setFieldValue throws:
  TypeError: Cannot assign to read only property 'type'

Fix to follow in next commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🧪 Test Selection

✅ Tests that will run

Test Description
Preview Environment Deploys a preview environment for testing
Frontend E2E Tests Runs Cypress app tests

⏭️ Tests skipped (no relevant file changes detected)

Test How to trigger manually
Backend API Tests Add test-backend to PR description
Timezone Tests Add test-timezone to PR description
CLI Tests Add test-cli to PR description

Tip: Add test-all to your PR description to run all tests.

@github-actions
Copy link
Copy Markdown

Your preview environment pr-22065 has been deployed.

Preview environment endpoints are available at:

@github-actions
Copy link
Copy Markdown

Preview Environment

🌐 URL: https://lightdash-preview-pr-22065.lightdash.okteto.dev

📋 Logs: View in GCP Console

🔧 SSH: ./scripts/okteto-ssh.sh 22065

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants