Skip to content

[Discover] Fix Discover tab initialization#245752

Merged
davismcphee merged 4 commits intoelastic:mainfrom
davismcphee:fix-discover-tab-initialization
Dec 10, 2025
Merged

[Discover] Fix Discover tab initialization#245752
davismcphee merged 4 commits intoelastic:mainfrom
davismcphee:fix-discover-tab-initialization

Conversation

@davismcphee
Copy link
Copy Markdown
Contributor

@davismcphee davismcphee commented Dec 10, 2025

Summary

This PR fixes the Discover tab initialization logic to prevent the following:

  • State leaking between tabs when switching to another tab while the previous tab is still initializing, caused by syncing tab state with global Kibana services.
  • Duplicate tab initializations when switching away from and back to a tab before initialization completes, caused by the initialization logic checking for the existence of DiscoverStateContainer instead of a dedicated status property.

These are the main fixes:

  • Move retrieving the initial URL state to the start of tab initialization before any async work in case the current tab (and URL) changes while initializing.
  • Avoid the following if the current tab changes during tab initialization:
    • Syncing tab state to global services, which overrides the current tab's state.
    • Calling stateContainer.actions.initializeAndSync(), which causes the wrong tab to be synced to the URL and global services.
    • Calling stateContainer.actions.fetchData(true), which results in the wrong search parameters being used during data fetching.
  • Stop relying on DiscoverStateContainer to check if a tab is initialized, and instead introduce a dedicated TabInitializationStatus to prevent duplicate initializations when switching away from and back to a tab during initialization.

Fixes #245754.

Checklist

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.

Identify risks

  • This should probably be backported to 9.2 since it's a bad bug, but there are some significant changes to the tab initialization logic. We should test thoroughly for regressions before merging, and in the 9.2 backport.
…itialization to avoid leaking tab state, and avoid initiating data fetching until reselected since it relies on global services
@davismcphee davismcphee self-assigned this Dec 10, 2025
@davismcphee davismcphee added release_note:fix Team:DataDiscovery Discover, search (data plugin and KQL), data views, saved searches. For ES|QL, use Team:ES|QL. t// backport:version Backport to applied version labels v9.2.3 labels Dec 10, 2025
Comment on lines +20 to +28
export const InitializationError = ({
error: originalError,
}: {
error: Error | SerializedError;
}) => {
const error = useMemo(
() => (originalError instanceof Error ? originalError : new Error(originalError.message)),
[originalError]
);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to account for the possibility of SerializedError now since error is coming from the Redux store.


return {
status: getPreviewStatus(fetchStatus),
status: tabState.forceFetchOnSelect ? TabStatus.DEFAULT : getPreviewStatus(fetchStatus),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to use the default preview status when forceFetchOnSelect === true since whatever results the tab has are no longer valid.

getState,
{ services, runtimeStateManager, urlStateStorage, searchSessionManager }
) => {
export const initializeSingleTab = createInternalStateAsyncThunk(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migrated to createInternalStateAsyncThunk so we can sync the TabInitializationStatus when initializing.

Comment on lines +306 to +308
dispatch(
internalStateSlice.actions.setForceFetchOnSelect({ tabId, forceFetchOnSelect: true })
);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we could start fetching even if the user changed tabs, but our fetching logic relies on global services, so using forceFetchOnSelect is much lower impact in the meantime.

const withTab = <TPayload extends TabActionPayload>(
state: DiscoverInternalState,
action: TAction,
payload: TPayload,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to payload so we can use withTab in builder.addCase() too.

Comment on lines +369 to +376
builder.addCase(initializeSingleTab.rejected, (state, action) =>
withTab(state, action.meta.arg, (tab) => {
tab.initializationState = {
initializationStatus: TabInitializationStatus.Error,
error: action.error,
};
})
);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will unfortunately put SavedObjectNotFound into the Redux store which isn't serializable (and partially why I originally handled it in the component). But the multiple initializations bug is worse, and there's not a great alternative with how RedirectWhenSavedObjectNotFound currently works.

We should change the redirect logic at some point to get rid of the SavedObjectNotFound weirdness, which would fix this too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to have FTR tests for these fixes, but I'm not sure of a good way to delay tab initialization in order to test it. Open to any suggestions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dmlemeshko,
Do we have any configuration options for FTR to slow down network requests or to make the backend to handle requests slower?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to merge this for now to get the fix in, but totally open to adding FTR tests for it as a followup if we think of a good way.

@kibanamachine
Copy link
Copy Markdown
Contributor

Flaky Test Runner Stats

🟠 Some tests failed. - kibana-flaky-test-suite-runner#10030

[✅] src/platform/test/functional/apps/discover/tabs/config.ts: 25/25 tests passed.
[❌] src/platform/test/functional/apps/discover/tabs2/config.ts: 0/25 tests passed.
[✅] src/platform/test/functional/apps/discover/tabs3/config.ts: 25/25 tests passed.
[✅] src/platform/test/functional/apps/discover/tabs_disabled/config.ts: 25/25 tests passed.

see run history

@kibanamachine
Copy link
Copy Markdown
Contributor

Flaky Test Runner Stats

🎉 All tests passed! - kibana-flaky-test-suite-runner#10031

[✅] src/platform/test/functional/apps/discover/tabs_disabled/config.ts: 25/25 tests passed.
[✅] src/platform/test/functional/apps/discover/tabs/config.ts: 25/25 tests passed.
[✅] src/platform/test/functional/apps/discover/tabs2/config.ts: 25/25 tests passed.
[✅] src/platform/test/functional/apps/discover/tabs3/config.ts: 25/25 tests passed.

see run history

},
...existingTab,
...item,
...omit(item, 'initializationState'),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't let tab state updates overwrite the initializationState, it should only be changed via initializeSingleTab.


export const selectTab = (state: DiscoverInternalState, tabId: string) =>
state.tabs.byId[tabId] ?? state.tabs.recentlyClosedTabsById[tabId];
export const selectTab = (state: DiscoverInternalState, tabId: string) => state.tabs.byId[tabId];
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is one piece I was a bit iffy on, but afaict it should be ok.

We used to select from recently closed tabs too, but this actually caused an existing subtle bug where resetting unsaved changes with deleted tabs would actually pull in the recently closed tab state when resetting, instead of basing it just on the persistedDiscoverSession tab state. This issue was surfaced in this PR since it was pulling in an invalid initializationState.

It looks like anywhere we currently access recently closed tabs uses selectRecentlyClosedTabs instead, and I was unable to find any drawbacks to changing this.

@jughosta Maybe you have more thoughts on this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes make sense.

@davismcphee davismcphee marked this pull request as ready for review December 10, 2025 13:54
@davismcphee davismcphee requested a review from a team as a code owner December 10, 2025 13:54
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/kibana-data-discovery (Team:DataDiscovery)

Copy link
Copy Markdown
Contributor

@jughosta jughosta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍
Thanks for this important fix!


export const selectTab = (state: DiscoverInternalState, tabId: string) =>
state.tabs.byId[tabId] ?? state.tabs.recentlyClosedTabsById[tabId];
export const selectTab = (state: DiscoverInternalState, tabId: string) => state.tabs.byId[tabId];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes make sense.

@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Dec 10, 2025

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
discover 1.3MB 1.3MB +1.1KB

History

cc @davismcphee

@davismcphee davismcphee merged commit 12ae847 into elastic:main Dec 10, 2025
12 checks passed
@davismcphee davismcphee deleted the fix-discover-tab-initialization branch December 10, 2025 23:41
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.2

https://github.com/elastic/kibana/actions/runs/20116870797

@kibanamachine
Copy link
Copy Markdown
Contributor

💔 All backports failed

Status Branch Result
9.2 Backport failed because of merge conflicts

Manual backport

To create the backport manually run:

node scripts/backport --pr 245752

Questions ?

Please refer to the Backport tool documentation

@kibanamachine kibanamachine added the backport missing Added to PRs automatically when the are determined to be missing a backport. label Dec 11, 2025
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 245752 locally
cc: @davismcphee

@davismcphee
Copy link
Copy Markdown
Contributor Author

💚 All backports created successfully

Status Branch Result
9.2

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

davismcphee added a commit to davismcphee/kibana that referenced this pull request Dec 12, 2025
## Summary

This PR fixes the Discover tab initialization logic to prevent the
following:
- State leaking between tabs when switching to another tab while the
previous tab is still initializing, caused by syncing tab state with
global Kibana services.
- Duplicate tab initializations when switching away from and back to a
tab before initialization completes, caused by the initialization logic
checking for the existence of `DiscoverStateContainer` instead of a
dedicated status property.

These are the main fixes:
- Move retrieving the initial URL state to the start of tab
initialization before any async work in case the current tab (and URL)
changes while initializing.
- Avoid the following if the current tab changes during tab
initialization:
- Syncing tab state to global services, which overrides the current
tab's state.
- Calling `stateContainer.actions.initializeAndSync()`, which causes the
wrong tab to be synced to the URL and global services.
- Calling `stateContainer.actions.fetchData(true)`, which results in the
wrong search parameters being used during data fetching.
- Stop relying on `DiscoverStateContainer` to check if a tab is
initialized, and instead introduce a dedicated `TabInitializationStatus`
to prevent duplicate initializations when switching away from and back
to a tab during initialization.

Fixes elastic#245754.

### Checklist

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [x] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
- [x] Review the [backport
guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)
and apply applicable `backport:*` labels.

### Identify risks

- This should probably be backported to 9.2 since it's a bad bug, but
there are some significant changes to the tab initialization logic. We
should test thoroughly for regressions before merging, and in the 9.2
backport.

(cherry picked from commit 12ae847)

# Conflicts:
#	src/platform/plugins/shared/discover/public/application/main/components/tabs_view/use_preview_data.ts
#	src/platform/plugins/shared/discover/public/application/main/state_management/redux/actions/initialize_single_tab.ts
#	src/platform/plugins/shared/discover/public/application/main/state_management/redux/internal_state.ts
#	src/platform/plugins/shared/discover/public/application/main/state_management/redux/tab_mapping_utils.test.ts
#	src/platform/plugins/shared/discover/public/application/main/state_management/redux/types.ts
davismcphee added a commit that referenced this pull request Dec 12, 2025
# Backport

This will backport the following commits from `main` to `9.2`:
- [[Discover] Fix Discover tab initialization
(#245752)](#245752)

<!--- Backport version: 10.2.0 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Davis
McPhee","email":"davis.mcphee@elastic.co"},"sourceCommit":{"committedDate":"2025-12-10T23:41:31Z","message":"[Discover]
Fix Discover tab initialization (#245752)\n\n## Summary\n\nThis PR fixes
the Discover tab initialization logic to prevent the\nfollowing:\n-
State leaking between tabs when switching to another tab while
the\nprevious tab is still initializing, caused by syncing tab state
with\nglobal Kibana services.\n- Duplicate tab initializations when
switching away from and back to a\ntab before initialization completes,
caused by the initialization logic\nchecking for the existence of
`DiscoverStateContainer` instead of a\ndedicated status
property.\n\nThese are the main fixes:\n- Move retrieving the initial
URL state to the start of tab\ninitialization before any async work in
case the current tab (and URL)\nchanges while initializing.\n- Avoid the
following if the current tab changes during tab\ninitialization:\n-
Syncing tab state to global services, which overrides the current\ntab's
state.\n- Calling `stateContainer.actions.initializeAndSync()`, which
causes the\nwrong tab to be synced to the URL and global services.\n-
Calling `stateContainer.actions.fetchData(true)`, which results in
the\nwrong search parameters being used during data fetching.\n- Stop
relying on `DiscoverStateContainer` to check if a tab is\ninitialized,
and instead introduce a dedicated `TabInitializationStatus`\nto prevent
duplicate initializations when switching away from and back\nto a tab
during initialization.\n\nFixes #245754.\n\n### Checklist\n\n- [ ] Any
text added follows [EUI's
writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\nsentence case text and includes
[i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n-
[
]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas
added for features that require explanation or tutorials\n- [ ] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [ ] If a plugin
configuration key changed, check if it needs to be\nallowlisted in the
cloud and added to the
[docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n-
[x] This was checked for breaking HTTP API changes, and any
breaking\nchanges have been approved by the breaking-change committee.
The\n`release_note:breaking` label should be applied in these
situations.\n- [x] [Flaky
Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\nused on any tests changed\n- [x] The PR description includes the
appropriate Release Notes section,\nand the correct `release_note:*`
label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n-
[x] Review the
[backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand
apply applicable `backport:*` labels.\n\n### Identify risks\n\n- This
should probably be backported to 9.2 since it's a bad bug, but\nthere
are some significant changes to the tab initialization logic. We\nshould
test thoroughly for regressions before merging, and in the
9.2\nbackport.","sha":"12ae8477cbe4641c636f043fb1601539f33fac5c","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","backport
missing","Team:DataDiscovery","backport:version","v9.3.0","v9.2.3"],"title":"[Discover]
Fix Discover tab
initialization","number":245752,"url":"https://github.com/elastic/kibana/pull/245752","mergeCommit":{"message":"[Discover]
Fix Discover tab initialization (#245752)\n\n## Summary\n\nThis PR fixes
the Discover tab initialization logic to prevent the\nfollowing:\n-
State leaking between tabs when switching to another tab while
the\nprevious tab is still initializing, caused by syncing tab state
with\nglobal Kibana services.\n- Duplicate tab initializations when
switching away from and back to a\ntab before initialization completes,
caused by the initialization logic\nchecking for the existence of
`DiscoverStateContainer` instead of a\ndedicated status
property.\n\nThese are the main fixes:\n- Move retrieving the initial
URL state to the start of tab\ninitialization before any async work in
case the current tab (and URL)\nchanges while initializing.\n- Avoid the
following if the current tab changes during tab\ninitialization:\n-
Syncing tab state to global services, which overrides the current\ntab's
state.\n- Calling `stateContainer.actions.initializeAndSync()`, which
causes the\nwrong tab to be synced to the URL and global services.\n-
Calling `stateContainer.actions.fetchData(true)`, which results in
the\nwrong search parameters being used during data fetching.\n- Stop
relying on `DiscoverStateContainer` to check if a tab is\ninitialized,
and instead introduce a dedicated `TabInitializationStatus`\nto prevent
duplicate initializations when switching away from and back\nto a tab
during initialization.\n\nFixes #245754.\n\n### Checklist\n\n- [ ] Any
text added follows [EUI's
writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\nsentence case text and includes
[i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n-
[
]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas
added for features that require explanation or tutorials\n- [ ] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [ ] If a plugin
configuration key changed, check if it needs to be\nallowlisted in the
cloud and added to the
[docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n-
[x] This was checked for breaking HTTP API changes, and any
breaking\nchanges have been approved by the breaking-change committee.
The\n`release_note:breaking` label should be applied in these
situations.\n- [x] [Flaky
Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\nused on any tests changed\n- [x] The PR description includes the
appropriate Release Notes section,\nand the correct `release_note:*`
label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n-
[x] Review the
[backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand
apply applicable `backport:*` labels.\n\n### Identify risks\n\n- This
should probably be backported to 9.2 since it's a bad bug, but\nthere
are some significant changes to the tab initialization logic. We\nshould
test thoroughly for regressions before merging, and in the
9.2\nbackport.","sha":"12ae8477cbe4641c636f043fb1601539f33fac5c"}},"sourceBranch":"main","suggestedTargetBranches":["9.2"],"targetPullRequestStates":[{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/245752","number":245752,"mergeCommit":{"message":"[Discover]
Fix Discover tab initialization (#245752)\n\n## Summary\n\nThis PR fixes
the Discover tab initialization logic to prevent the\nfollowing:\n-
State leaking between tabs when switching to another tab while
the\nprevious tab is still initializing, caused by syncing tab state
with\nglobal Kibana services.\n- Duplicate tab initializations when
switching away from and back to a\ntab before initialization completes,
caused by the initialization logic\nchecking for the existence of
`DiscoverStateContainer` instead of a\ndedicated status
property.\n\nThese are the main fixes:\n- Move retrieving the initial
URL state to the start of tab\ninitialization before any async work in
case the current tab (and URL)\nchanges while initializing.\n- Avoid the
following if the current tab changes during tab\ninitialization:\n-
Syncing tab state to global services, which overrides the current\ntab's
state.\n- Calling `stateContainer.actions.initializeAndSync()`, which
causes the\nwrong tab to be synced to the URL and global services.\n-
Calling `stateContainer.actions.fetchData(true)`, which results in
the\nwrong search parameters being used during data fetching.\n- Stop
relying on `DiscoverStateContainer` to check if a tab is\ninitialized,
and instead introduce a dedicated `TabInitializationStatus`\nto prevent
duplicate initializations when switching away from and back\nto a tab
during initialization.\n\nFixes #245754.\n\n### Checklist\n\n- [ ] Any
text added follows [EUI's
writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\nsentence case text and includes
[i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n-
[
]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas
added for features that require explanation or tutorials\n- [ ] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [ ] If a plugin
configuration key changed, check if it needs to be\nallowlisted in the
cloud and added to the
[docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n-
[x] This was checked for breaking HTTP API changes, and any
breaking\nchanges have been approved by the breaking-change committee.
The\n`release_note:breaking` label should be applied in these
situations.\n- [x] [Flaky
Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\nused on any tests changed\n- [x] The PR description includes the
appropriate Release Notes section,\nand the correct `release_note:*`
label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n-
[x] Review the
[backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand
apply applicable `backport:*` labels.\n\n### Identify risks\n\n- This
should probably be backported to 9.2 since it's a bad bug, but\nthere
are some significant changes to the tab initialization logic. We\nshould
test thoroughly for regressions before merging, and in the
9.2\nbackport.","sha":"12ae8477cbe4641c636f043fb1601539f33fac5c"}},{"branch":"9.2","label":"v9.2.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
@kibanamachine kibanamachine removed the backport missing Added to PRs automatically when the are determined to be missing a backport. label Dec 12, 2025
seanrathier pushed a commit to seanrathier/kibana that referenced this pull request Dec 15, 2025
## Summary

This PR fixes the Discover tab initialization logic to prevent the
following:
- State leaking between tabs when switching to another tab while the
previous tab is still initializing, caused by syncing tab state with
global Kibana services.
- Duplicate tab initializations when switching away from and back to a
tab before initialization completes, caused by the initialization logic
checking for the existence of `DiscoverStateContainer` instead of a
dedicated status property.

These are the main fixes:
- Move retrieving the initial URL state to the start of tab
initialization before any async work in case the current tab (and URL)
changes while initializing.
- Avoid the following if the current tab changes during tab
initialization:
- Syncing tab state to global services, which overrides the current
tab's state.
- Calling `stateContainer.actions.initializeAndSync()`, which causes the
wrong tab to be synced to the URL and global services.
- Calling `stateContainer.actions.fetchData(true)`, which results in the
wrong search parameters being used during data fetching.
- Stop relying on `DiscoverStateContainer` to check if a tab is
initialized, and instead introduce a dedicated `TabInitializationStatus`
to prevent duplicate initializations when switching away from and back
to a tab during initialization.

Fixes elastic#245754.

### Checklist

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [x] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
- [x] Review the [backport
guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)
and apply applicable `backport:*` labels.

### Identify risks

- This should probably be backported to 9.2 since it's a bad bug, but
there are some significant changes to the tab initialization logic. We
should test thoroughly for regressions before merging, and in the 9.2
backport.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels release_note:fix Team:DataDiscovery Discover, search (data plugin and KQL), data views, saved searches. For ES|QL, use Team:ES|QL. t// v9.2.3 v9.3.0

5 participants