diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
index 8085fcb942d81..8241c26ccae99 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
@@ -73,6 +73,12 @@
"navigation": "Navigation: Shift+{{arrow}}",
"toggleGroup": "Toggle group: Space"
},
+ "notFound": {
+ "back": "Go Back",
+ "backToDags": "Back to Dags",
+ "message": "The Dag \"{{dagId}}\" does not exist.",
+ "title": "Dag Not Found"
+ },
"overview": {
"buttons": {
"failedRun_one": "Failed Run",
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Dag.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Dag.tsx
index 3ba287faffd2e..4ea3fa73d551b 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Dag.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Dag.tsx
@@ -26,6 +26,7 @@ import { RiArrowGoBackFill } from "react-icons/ri";
import { useParams } from "react-router-dom";
import { useDagServiceGetDagDetails, useDagServiceGetLatestRunInfo } from "openapi/queries";
+import { ApiError } from "openapi/requests/core/ApiError";
import { TaskIcon } from "src/assets/TaskIcon";
import { usePluginTabs } from "src/hooks/usePluginTabs";
import { useRequiredActionTabs } from "src/hooks/useRequiredActionTabs";
@@ -33,6 +34,7 @@ import { DetailsLayout } from "src/layouts/Details/DetailsLayout";
import { useRefreshOnNewDagRuns } from "src/queries/useRefreshOnNewDagRuns";
import { isStatePending, useAutoRefresh } from "src/utils";
+import { DagNotFound } from "./DagNotFound";
import { Header } from "./Header";
export const Dag = () => {
@@ -103,6 +105,11 @@ export const Dag = () => {
return true;
});
+ // Handle 404 error when Dag is not found
+ if (error instanceof ApiError && error.status === 404) {
+ return ;
+ }
+
return (
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/DagNotFound.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/DagNotFound.tsx
new file mode 100644
index 0000000000000..0a667e8ef63a8
--- /dev/null
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/DagNotFound.tsx
@@ -0,0 +1,70 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Box, Button, Container, Heading, HStack, Text, VStack } from "@chakra-ui/react";
+import { useTranslation } from "react-i18next";
+import { useNavigate } from "react-router-dom";
+
+import { AirflowPin } from "src/assets/AirflowPin";
+
+type DagNotFoundProps = {
+ readonly dagId: string;
+};
+
+export const DagNotFound = ({ dagId }: DagNotFoundProps) => {
+ const navigate = useNavigate();
+ const { t: translate } = useTranslation("dag");
+
+ return (
+
+
+
+
+
+
+ 404
+ {translate("notFound.title")}
+ {translate("notFound.message", { dagId })}
+
+
+
+
+
+
+
+
+
+ );
+};