From 5d4d8de2354a2003c66f3734400c98e3df09f003 Mon Sep 17 00:00:00 2001
From: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
Date: Sat, 17 Oct 2026 19:16:08 +0530
Subject: [PATCH 1/3] Keep a typed alert argument search when the source search
is rebuilt
Adding a filter re-asks the server what the selection supports, which hands
the argument autocomplete a new sourceSearch. debouncedSearch depended on it,
so it was rebuilt and the cleanup cancelled the search the user was still
typing: the text stayed in the input but no search request was ever sent.
Read the search params through a ref so the debounced function is created
once and only cancelled on unmount.
This is the cause of the intermittent NotificationAlerts > Multiple Filters
Alert timeouts in the merge queue.
---
.../AlertAiFormFields.component.test.tsx | 59 ++++++++++++++++++-
.../Alerts/AlertAiRuleSection.component.tsx | 25 ++++++--
2 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx
index 94c836415c7e..aa83e4bbee7a 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx
@@ -53,12 +53,15 @@ import {
import { testAlertDestination } from '../../../rest/alertsAPI';
import { searchQuery } from '../../../rest/searchAPI';
import alertsClassBase from '../../../utils/AlertsClassBase';
+import { AlertSourceSearch } from '../../../utils/Alerts/AlertSourceSearch';
import AlertAiDestinationConfigFields from './AlertAiDestinationConfigFields.component';
import AlertAiDestinationItem from './AlertAiDestinationItem.component';
import AlertAiDestinationSection from './AlertAiDestinationSection.component';
import AlertAiForm from './AlertAiForm.component';
import AlertAiFormFields from './AlertAiFormFields.component';
-import AlertAiRuleSection from './AlertAiRuleSection.component';
+import AlertAiRuleSection, {
+ RuleArgumentField,
+} from './AlertAiRuleSection.component';
import AlertAiSection from './AlertAiSection.component';
import AlertDescriptionCard from './AlertDescriptionCard.component';
@@ -859,6 +862,60 @@ describe('AlertAi form field components', () => {
);
});
+ it('keeps a typed search when the source search is rebuilt during the debounce', async () => {
+ jest.useFakeTimers();
+ const getSourceSearch = () =>
+ ({
+ byId: jest.fn(),
+ byName: jest.fn(),
+ containerEntities: [],
+ indexes: [],
+ } as unknown as AlertSourceSearch);
+ const value = {
+ ...baseValue,
+ input: {
+ filters: [
+ {
+ arguments: [{ input: [], name: 'domainList' }],
+ effect: Effect.Include,
+ name: 'matchAnyDomain',
+ },
+ ],
+ },
+ } as ModifiedCreateEventSubscription;
+ const renderField = (sourceSearch: AlertSourceSearch) => (
+
+ );
+
+ const { rerender } = render(renderField(getSourceSearch()));
+ await act(async () => {
+ jest.advanceTimersByTime(0);
+ });
+ (searchQuery as jest.Mock).mockClear();
+
+ fireEvent.change(screen.getByTestId('domainList-autocomplete'), {
+ target: { value: 'dom' },
+ });
+ // Adding a filter re-asks the server what the selection supports, which hands the field
+ // a new source search while the typed text is still waiting on the debounce.
+ rerender(renderField(getSourceSearch()));
+ await act(async () => {
+ jest.advanceTimersByTime(500);
+ });
+
+ expect(searchQuery).toHaveBeenCalledWith(
+ expect.objectContaining({ query: 'dom' })
+ );
+ });
+
it('renders fixed runtime options with the fqn autocomplete contract', () => {
const onChange = jest.fn();
const selectedRule: ArgumentsInput = {
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiRuleSection.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiRuleSection.component.tsx
index f63728690fe5..dbf7296213a3 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiRuleSection.component.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiRuleSection.component.tsx
@@ -316,15 +316,30 @@ const AiArgumentAutocomplete = ({
[hasNoResults, items, t]
);
+ // Read through a ref so a new source search (the server re-answers capabilities whenever the
+ // filters change) does not recreate, and so cancel, a search the user is still typing.
+ const searchParamsRef = useRef({
+ argument,
+ containerEntities: stableContainerEntities,
+ selectedSource,
+ sourceSearch,
+ });
+
+ useEffect(() => {
+ searchParamsRef.current = {
+ argument,
+ containerEntities: stableContainerEntities,
+ selectedSource,
+ sourceSearch,
+ };
+ }, [argument, selectedSource, sourceSearch, stableContainerEntities]);
+
const debouncedSearch = useMemo(
() =>
debounce(async (searchText: string) => {
const nextItems = await searchAlertAiArgumentOptions({
- argument,
- containerEntities: stableContainerEntities,
+ ...searchParamsRef.current,
searchText,
- selectedSource,
- sourceSearch,
});
setHasNoResults(searchText.trim() !== '' && nextItems.length === 0);
@@ -336,7 +351,7 @@ const AiArgumentAutocomplete = ({
)
);
}, 500),
- [argument, selectedSource, sourceSearch, stableContainerEntities]
+ []
);
useEffect(
From 95f3e255819a0c9e4ec1d1c90ce4bc430cffabb0 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sat, 17 Oct 2026 13:47:10 +0000
Subject: [PATCH 2/3] chore(playwright): auto-refresh impact-map.generated.json
---
.github/playwright/impact-map.generated.json | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/playwright/impact-map.generated.json b/.github/playwright/impact-map.generated.json
index a5c2053bdd35..4748d14360fc 100644
--- a/.github/playwright/impact-map.generated.json
+++ b/.github/playwright/impact-map.generated.json
@@ -3328,6 +3328,7 @@
"playwright/e2e/Features/AdvancedSearch.spec.ts",
"playwright/e2e/Features/ContextCenterDashboard.spec.ts",
"playwright/e2e/Features/DataQuality/IncidentManagerSqlQuery.spec.ts",
+ "playwright/e2e/Features/DataQuality/ProfilerIngestionForm.spec.ts",
"playwright/e2e/Features/DataQuality/TableTestCaseExportFilters.spec.ts",
"playwright/e2e/Features/DomainFilterQueryFilter.spec.ts",
"playwright/e2e/Features/LandingPageWidgets/LandingPageContextCenter.spec.ts",
@@ -8668,6 +8669,7 @@
"openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.component.tsx"
],
"specs": [
+ "playwright/e2e/Features/DataQuality/ProfilerIngestionForm.spec.ts",
"playwright/e2e/Features/StorageMetadataAgentForm.spec.ts"
]
},
From 2ff8254295be0423f1cfb1e69e943c307b926159 Mon Sep 17 00:00:00 2001
From: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
Date: Sat, 17 Oct 2026 22:31:39 +0530
Subject: [PATCH 3/3] Fix UI checkstyle
---
.../observability/Alerts/AlertAiFormFields.component.test.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx
index aa83e4bbee7a..4f6dfb81172b 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/observability/Alerts/AlertAiFormFields.component.test.tsx
@@ -52,8 +52,8 @@ import {
} from '../../../pages/AddObservabilityPage/AddObservabilityPage.interface';
import { testAlertDestination } from '../../../rest/alertsAPI';
import { searchQuery } from '../../../rest/searchAPI';
-import alertsClassBase from '../../../utils/AlertsClassBase';
import { AlertSourceSearch } from '../../../utils/Alerts/AlertSourceSearch';
+import alertsClassBase from '../../../utils/AlertsClassBase';
import AlertAiDestinationConfigFields from './AlertAiDestinationConfigFields.component';
import AlertAiDestinationItem from './AlertAiDestinationItem.component';
import AlertAiDestinationSection from './AlertAiDestinationSection.component';