This is an automated email from the ASF dual-hosted git repository.

kaxilnaik pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit a524ff8eeec8c0bca40a7d78964448d180ff1365
Author: Guan Ming(Wesley) Chiu <[email protected]>
AuthorDate: Thu Sep 18 06:30:19 2025 +0800

    Fix mapIndex type validation error (#55794)
    
    (cherry picked from commit 7f9a96aa54327729c0bc737ac20cf43cad624a84)
---
 .../src/airflow/ui/src/hooks/useSelectedVersion.ts   |  6 ++++--
 .../airflow/ui/src/layouts/Details/DagBreadcrumb.tsx |  5 +++--
 .../ui/src/pages/TaskInstance/AssetEvents.tsx        | 20 ++++++++++++++------
 .../airflow/ui/src/pages/TaskInstance/Details.tsx    | 19 +++++++++++++------
 .../airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx  | 19 +++++++++++++------
 .../ui/src/pages/TaskInstance/TaskInstance.tsx       | 13 ++++++++++---
 6 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/hooks/useSelectedVersion.ts 
b/airflow-core/src/airflow/ui/src/hooks/useSelectedVersion.ts
index fb33fca1719..a5c33c981bc 100644
--- a/airflow-core/src/airflow/ui/src/hooks/useSelectedVersion.ts
+++ b/airflow-core/src/airflow/ui/src/hooks/useSelectedVersion.ts
@@ -65,18 +65,20 @@ const useSelectedVersion = (): number | undefined => {
 
   const taskNode = structureData?.nodes.find((node) => node.id === taskId);
   const isMapped = taskNode?.is_mapped;
+  const parsedMapIndex = parseInt(mapIndex, 10);
 
   const { data: mappedTaskInstanceData } = 
useTaskInstanceServiceGetMappedTaskInstance(
     {
       dagId,
       dagRunId: runId,
-      mapIndex: parseInt(mapIndex, 10),
+      mapIndex: parsedMapIndex,
       taskId,
     },
     undefined,
     // Do not enable on a task instance summary. (mapped task but no mapIndex 
defined)
     {
-      enabled: taskNode !== undefined && !Boolean(mapIndex === "-1" && 
isMapped),
+      enabled:
+        taskNode !== undefined && !Boolean(parsedMapIndex === -1 && isMapped) 
&& !isNaN(parsedMapIndex),
     },
   );
 
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/DagBreadcrumb.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/DagBreadcrumb.tsx
index b9d144944b6..c93475ecbfd 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/DagBreadcrumb.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/DagBreadcrumb.tsx
@@ -36,6 +36,7 @@ export const DagBreadcrumb = () => {
   const { t: translate } = useTranslation();
   const { dagId = "", groupId, mapIndex = "-1", runId, taskId } = useParams();
   const refetchInterval = useAutoRefresh({ dagId });
+  const parsedMapIndex = parseInt(mapIndex, 10);
 
   const { data: dag } = useDagServiceGetDagDetails({
     dagId,
@@ -56,9 +57,9 @@ export const DagBreadcrumb = () => {
   const { data: task } = useTaskServiceGetTask({ dagId, taskId }, undefined, { 
enabled: Boolean(taskId) });
 
   const { data: mappedTaskInstance } = 
useTaskInstanceServiceGetMappedTaskInstance(
-    { dagId, dagRunId: runId ?? "", mapIndex: parseInt(mapIndex, 10), taskId: 
taskId ?? "" },
+    { dagId, dagRunId: runId ?? "", mapIndex: parsedMapIndex, taskId: taskId 
?? "" },
     undefined,
-    { enabled: Boolean(runId) && Boolean(taskId) && mapIndex !== "-1" },
+    { enabled: Boolean(runId) && Boolean(taskId) && mapIndex !== "-1" && 
!isNaN(parsedMapIndex) },
   );
 
   const links: Array<{ label: ReactNode | string; labelExtra?: ReactNode; 
title?: string; value?: string }> =
diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/AssetEvents.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/AssetEvents.tsx
index 56081790d32..7e2fd720863 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/AssetEvents.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/AssetEvents.tsx
@@ -25,12 +25,20 @@ import { isStatePending, useAutoRefresh } from "src/utils";
 export const AssetEvents = () => {
   const { dagId = "", mapIndex = "-1", runId = "", taskId = "" } = useParams();
 
-  const { data: taskInstance } = useTaskInstanceServiceGetMappedTaskInstance({
-    dagId,
-    dagRunId: runId,
-    mapIndex: parseInt(mapIndex, 10),
-    taskId,
-  });
+  const parsedMapIndex = parseInt(mapIndex, 10);
+
+  const { data: taskInstance } = useTaskInstanceServiceGetMappedTaskInstance(
+    {
+      dagId,
+      dagRunId: runId,
+      mapIndex: parsedMapIndex,
+      taskId,
+    },
+    undefined,
+    {
+      enabled: !isNaN(parsedMapIndex),
+    },
+  );
 
   const refetchInterval = useAutoRefresh({ dagId });
 
diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx
index 15b35e4b5b4..400846d1e2a 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx
@@ -42,13 +42,20 @@ export const Details = () => {
   const [searchParams, setSearchParams] = useSearchParams();
 
   const tryNumberParam = searchParams.get(SearchParamsKeys.TRY_NUMBER);
+  const parsedMapIndex = parseInt(mapIndex, 10);
 
-  const { data: taskInstance } = useTaskInstanceServiceGetMappedTaskInstance({
-    dagId,
-    dagRunId: runId,
-    mapIndex: parseInt(mapIndex, 10),
-    taskId,
-  });
+  const { data: taskInstance } = useTaskInstanceServiceGetMappedTaskInstance(
+    {
+      dagId,
+      dagRunId: runId,
+      mapIndex: parsedMapIndex,
+      taskId,
+    },
+    undefined,
+    {
+      enabled: !isNaN(parsedMapIndex),
+    },
+  );
 
   const onSelectTryNumber = (newTryNumber: number) => {
     if (newTryNumber === taskInstance?.try_number) {
diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
index c03ec5c49cb..86678a308c6 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
@@ -41,17 +41,24 @@ export const Logs = () => {
   const tryNumberParam = searchParams.get(SearchParamsKeys.TRY_NUMBER);
   const logLevelFilters = searchParams.getAll(SearchParamsKeys.LOG_LEVEL);
   const sourceFilters = searchParams.getAll(SearchParamsKeys.SOURCE);
+  const parsedMapIndex = parseInt(mapIndex, 10);
 
   const {
     data: taskInstance,
     error,
     isLoading,
-  } = useTaskInstanceServiceGetMappedTaskInstance({
-    dagId,
-    dagRunId: runId,
-    mapIndex: parseInt(mapIndex, 10),
-    taskId,
-  });
+  } = useTaskInstanceServiceGetMappedTaskInstance(
+    {
+      dagId,
+      dagRunId: runId,
+      mapIndex: parsedMapIndex,
+      taskId,
+    },
+    undefined,
+    {
+      enabled: !isNaN(parsedMapIndex),
+    },
+  );
 
   const onSelectTryNumber = (newTryNumber: number) => {
     if (newTryNumber === taskInstance?.try_number) {
diff --git 
a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
index 0eb684f0d89..11f67d3df18 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import { Heading } from "@chakra-ui/react";
 import { ReactFlowProvider } from "@xyflow/react";
 import { useMemo } from "react";
 import { useTranslation } from "react-i18next";
@@ -34,7 +35,7 @@ import { isStatePending, useAutoRefresh } from "src/utils";
 import { Header } from "./Header";
 
 export const TaskInstance = () => {
-  const { t: translate } = useTranslation(["dag", "hitl"]);
+  const { t: translate } = useTranslation(["dag", "common", "hitl"]);
   const { dagId = "", mapIndex = "-1", runId = "", taskId = "" } = useParams();
   // Get external views with task_instance destination
   const externalTabs = usePluginTabs("task_instance");
@@ -56,6 +57,7 @@ export const TaskInstance = () => {
   ];
 
   const refetchInterval = useAutoRefresh({ dagId });
+  const parsedMapIndex = parseInt(mapIndex, 10);
 
   const {
     data: taskInstance,
@@ -65,11 +67,12 @@ export const TaskInstance = () => {
     {
       dagId,
       dagRunId: runId,
-      mapIndex: parseInt(mapIndex, 10),
+      mapIndex: parsedMapIndex,
       taskId,
     },
     undefined,
     {
+      enabled: !isNaN(parsedMapIndex),
       refetchInterval: (query) => (isStatePending(query.state.data?.state) ? 
refetchInterval : false),
     },
   );
@@ -108,7 +111,11 @@ export const TaskInstance = () => {
   return (
     <ReactFlowProvider>
       <DetailsLayout error={error} isLoading={isLoading} tabs={displayTabs}>
-        {taskInstance === undefined ? undefined : (
+        {taskInstance === undefined ? (
+          <Heading p={2} size="lg">
+            {translate("common:noItemsFound", { modelName: 
translate("common:taskInstance_one") })}
+          </Heading>
+        ) : (
           <Header
             isRefreshing={Boolean(isStatePending(taskInstance.state) && 
Boolean(refetchInterval))}
             taskInstance={taskInstance}

Reply via email to