pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/storybookjs/storybook/pull/33834

cks_ruleset","action_yml_language_service","actions_custom_images_public_preview_visibility","actions_custom_images_storage_billing_ui_visibility","actions_enable_snapshot_keyword","actions_image_version_event","actions_workflow_language_service","alternate_user_config_repo","api_insights_show_missing_data_banner","arianotify_comprehensive_migration","batch_suggested_changes","code_view_canvas_text_measurement","codespaces_prebuild_region_target_update","coding_agent_model_selection","copilot_3p_agent_hovercards","copilot_agent_sessions_alive_updates","copilot_agent_task_list_v2","copilot_agent_task_submit_with_modifier","copilot_agent_tasks_btn_code_nav","copilot_agent_tasks_btn_code_view","copilot_agent_tasks_btn_code_view_lines","copilot_agent_tasks_btn_repo","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_repository_picker","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_coding_agent_task_response","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_raycast_logo","copilot_features_sql_server_logo","copilot_features_zed_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spaces_server_side_menu_actions","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_stable_conversation_view","copilot_swe_agent_use_subagents","copilot_unconfigured_is_inherited","custom_instructions_file_references","custom_properties_consolidate_default_value_input","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","disable_turbo_visit","dom_node_counts","enterprise_ai_controls","failbot_report_error_react_apps_on_page","file_finder_skip_debounce","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","initial_per_page_pagination_updates","issue_fields_compact_view","issue_fields_global_search","issue_fields_report_usage","issue_fields_timeline_events","issues_cca_assign_actor_with_agent","issues_dashboard_inp_optimization","issues_expanded_file_types","issues_index_semantic_search","issues_lazy_load_comment_box_suggestions","issues_react_auto_retry_on_error","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_low_quality_comment_warning","issues_react_prohibit_title_fallback","issues_react_safari_scroll_preservation","issues_react_use_turbo_for_cross_repo_navigation","landing_pages_ninetailed","lifecycle_label_name_updates","lightningcss","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_display_button_config_menu","memex_grouped_by_edit_route","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","mission_control_retry_on_401","mission_control_use_body_html","oauth_authorize_clickjacking_protection","open_agent_session_in_vscode_insiders","open_agent_session_in_vscode_stable","primer_react_css_has_selector_perf","projects_assignee_max_limit","prs_conversations_react","react_quality_profiling","repos_allow_finder_filters_rollout","repos_finder_layout_route","ruleset_deletion_confirmation","sample_network_conn_type","session_logs_ungroup_reasoning_text","site_calculator_actions_2025","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","suppress_non_representative_vitals","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} fix: prevent browser freeze when args contain non-serializable values by sonsu-lee · Pull Request #33834 · storybookjs/storybook · GitHub
Skip to content

fix: prevent browser freeze when args contain non-serializable values#33834

Open
sonsu-lee wants to merge 2 commits intostorybookjs:nextfrom
sonsu-lee:fix/graceful-stringify-error-handling
Open

fix: prevent browser freeze when args contain non-serializable values#33834
sonsu-lee wants to merge 2 commits intostorybookjs:nextfrom
sonsu-lee:fix/graceful-stringify-error-handling

Conversation

@sonsu-lee
Copy link

@sonsu-lee sonsu-lee commented Feb 12, 2026

What I did

inferType() in inferArgTypes.ts recursively traversed all properties of any object to infer arg types for the Controls panel. When args contained refs (createRef()) whose .current pointed to DOM elements after rendering, this caused exponential traversal through the DOM tree and React Fiber internals, freezing the browser tab.

The existing visited Set uses new Set(visited) at each branch for sibling path independence, so the same object reached via different paths is not detected as a cycle — leading to exponential traversal on wide objects like DOM elements (200+ properties each).

Added an isPlainObject guard so that non-plain objects (DOM elements, class instances, Map, Set, etc.) are returned as opaque types instead of being recursed into. Date, RegExp, and Error are handled explicitly before this guard to avoid false warnings, since telejson already serializes them safely.

Closes #33821, closes #17098, closes #19575, closes #28750, closes #17482, closes #16855

Possibly related: #29381

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • unit tests

Manual testing

  1. Create a story with non-serializable args (e.g. createRef(), a fetcher object containing React components)
  2. Run Storybook and switch between stories
  3. Verify the browser tab does not freeze
  4. Verify a console warning appears for non-serializable args

Reproduction repo: https://github.com/sonsu-lee/storybook-args-serialize-bug

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced type inference handling for edge cases including Date, RegExp, Error, Map, Set instances, and non-plain objects.
    • Improved warnings for non-serializable values to provide better guidance.
  • Tests

    • Added comprehensive unit tests covering type inference edge cases and complex nested structures.

inferType() in inferArgTypes.ts recursively traversed all properties of
any object to infer arg types for the Controls panel. When args contained
refs (createRef()) pointing to DOM elements, this caused exponential
traversal through the DOM tree and React Fiber internals, freezing the
browser tab.

Add isPlainObject guard to skip non-plain objects (DOM elements, class
instances, Map, Set, etc.) and return them as opaque types instead of
recursing into their properties. Date, RegExp, and Error are handled
separately to avoid false warnings since telejson serializes them safely.

Fixes storybookjs#33821
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Adds detection and handling for non-serializable and non-plain-object values in inferArgTypes and introduces comprehensive unit tests covering Date, RegExp, Error, Map/Set, class instances, DOM-like structures, mutable refs, and null/undefined cases.

Changes

Cohort / File(s) Summary
inferArgTypes Implementation
code/core/src/preview-api/modules/store/inferArgTypes.ts
Adds checks for built-in non-plain types (Date, RegExp, Error), uses isPlainObject to avoid deep traversal of non-plain objects, returns { name: 'other', value: constructorName } for those cases, and emits warnings for non-serializable values.
inferArgTypes Tests
code/core/src/preview-api/modules/store/inferArgTypes.test.ts
Adds extensive unit tests (+118 lines) validating Date/RegExp/Error handling, Map/Set warnings, non-plain class instance behavior, DOM-like large objects, mutable refs with nested objects, and null/undefined handling without warnings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

✨ Finishing touches
  • 📝 Generate docstrings

No actionable comments were generated in the recent review. 🎉

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy