diff --git a/web/e2e/project/item/metadata/update.spec.ts b/web/e2e/project/item/metadata/update.spec.ts
new file mode 100644
index 0000000000..f3facfe1e4
--- /dev/null
+++ b/web/e2e/project/item/metadata/update.spec.ts
@@ -0,0 +1,41 @@
+import { closeNotification } from "@reearth-cms/e2e/common/notification";
+import { handleFieldForm } from "@reearth-cms/e2e/project/utils/field";
+import { createModel } from "@reearth-cms/e2e/project/utils/model";
+import { createProject, deleteProject } from "@reearth-cms/e2e/project/utils/project";
+import { expect, test } from "@reearth-cms/e2e/utils";
+
+test.beforeEach(async ({ reearth, page }) => {
+  await reearth.goto("/", { waitUntil: "domcontentloaded" });
+  await createProject(page);
+  await createModel(page);
+  await page.locator("li").filter({ hasText: "Text" }).locator("div").first().click();
+  await handleFieldForm(page, "text");
+  await page.getByText("Content").click();
+  await page.getByRole("button", { name: "plus New Item" }).click();
+  await page.getByRole("button", { name: "Save" }).click();
+  await closeNotification(page);
+  await page.getByText("Schema").click();
+  await page.getByRole("tab", { name: "Meta Data" }).click();
+  await page.locator("li").filter({ hasText: "Boolean" }).locator("div").first().click();
+  await handleFieldForm(page, "boolean");
+  await page.getByText("Content").click();
+});
+
+test.afterEach(async ({ page }) => {
+  await deleteProject(page);
+});
+
+test("Updating metadata added later from table has succeeded", async ({ page }) => {
+  await page.getByRole("switch").click();
+  await closeNotification(page);
+  await page.getByRole("link", { name: "edit", exact: true }).click();
+  await expect(page.getByLabel("boolean")).toHaveAttribute("aria-checked", "true");
+});
+
+test("Updating metadata added later from edit page has succeeded", async ({ page }) => {
+  await page.getByRole("link", { name: "edit", exact: true }).click();
+  await page.getByLabel("boolean").click();
+  await closeNotification(page);
+  await page.getByLabel("Back").click();
+  await expect(page.getByRole("switch")).toHaveAttribute("aria-checked", "true");
+});
diff --git a/web/src/components/molecules/Content/Details/index.tsx b/web/src/components/molecules/Content/Details/index.tsx
index adb23af0f5..5022da72a9 100644
--- a/web/src/components/molecules/Content/Details/index.tsx
+++ b/web/src/components/molecules/Content/Details/index.tsx
@@ -78,7 +78,7 @@ type Props = {
     metaFields: ItemField[];
   }) => Promise<void>;
   onItemUpdate: (data: { itemId: string; fields: ItemField[] }) => Promise<void>;
-  onMetaItemUpdate: (data: { metaItemId: string; metaFields: ItemField[] }) => Promise<void>;
+  onMetaItemUpdate: (data: { metaItemId?: string; metaFields: ItemField[] }) => Promise<void>;
   onBack: (modelId?: string) => void;
   onAssetsCreate: (files: UploadFile[]) => Promise<(Asset | undefined)[]>;
   onAssetCreateFromUrl: (url: string, autoUnzip: boolean) => Promise<Asset | undefined>;
diff --git a/web/src/components/molecules/Content/Form/index.tsx b/web/src/components/molecules/Content/Form/index.tsx
index e299fc58e4..889e773753 100644
--- a/web/src/components/molecules/Content/Form/index.tsx
+++ b/web/src/components/molecules/Content/Form/index.tsx
@@ -93,7 +93,7 @@ interface Props {
     metaFields: ItemField[];
   }) => Promise<void>;
   onItemUpdate: (data: { itemId: string; fields: ItemField[] }) => Promise<void>;
-  onMetaItemUpdate: (data: { metaItemId: string; metaFields: ItemField[] }) => Promise<void>;
+  onMetaItemUpdate: (data: { metaItemId?: string; metaFields: ItemField[] }) => Promise<void>;
   onBack: (modelId?: string) => void;
   onAssetsCreate: (files: UploadFile[]) => Promise<(Asset | undefined)[]>;
   onAssetCreateFromUrl: (url: string, autoUnzip: boolean) => Promise<Asset | undefined>;
@@ -403,7 +403,7 @@ const ContentForm: React.FC<Props> = ({
   }, [model, form, metaForm, itemId, onGroupGet, inputValueGet, onItemUpdate, onItemCreate]);
 
   const handleMetaUpdate = useCallback(async () => {
-    if (!itemId || !item?.metadata?.id) return;
+    if (!itemId) return;
     try {
       const metaValues = await metaForm.validateFields();
       const metaFields: { schemaFieldId: string; type: FieldType; value: string }[] = [];
@@ -414,8 +414,8 @@ const ContentForm: React.FC<Props> = ({
           type: model?.metadataSchema?.fields?.find(field => field.id === key)?.type as FieldType,
         });
       }
-      await onMetaItemUpdate?.({
-        metaItemId: item.metadata.id,
+      await onMetaItemUpdate({
+        metaItemId: item?.metadata?.id,
         metaFields,
       });
     } catch (info) {
diff --git a/web/src/components/organisms/Project/Content/ContentDetails/hooks.ts b/web/src/components/organisms/Project/Content/ContentDetails/hooks.ts
index 4856ae2c93..b23738323a 100644
--- a/web/src/components/organisms/Project/Content/ContentDetails/hooks.ts
+++ b/web/src/components/organisms/Project/Content/ContentDetails/hooks.ts
@@ -289,21 +289,58 @@ export default () => {
   );
 
   const handleMetaItemUpdate = useCallback(
-    async ({ metaItemId, metaFields }: { metaItemId: string; metaFields: ItemField[] }) => {
-      const item = await updateItem({
-        variables: {
-          itemId: metaItemId,
-          fields: metaFields as ItemFieldInput[],
-          version: currentItem?.metadata?.version ?? "",
-        },
-      });
-      if (item.errors || !item.data?.updateItem) {
+    async ({ metaItemId, metaFields }: { metaItemId?: string; metaFields: ItemField[] }) => {
+      if (metaItemId) {
+        const item = await updateItem({
+          variables: {
+            itemId: metaItemId,
+            fields: metaFields as ItemFieldInput[],
+            version: currentItem?.metadata?.version ?? "",
+          },
+        });
+        if (item.errors || !item.data?.updateItem) {
+          Notification.error({ message: t("Failed to update item.") });
+          return;
+        }
+      } else if (
+        currentItem &&
+        currentItem.fields &&
+        currentModel?.id &&
+        currentModel.metadataSchema.id
+      ) {
+        const metaItem = await createItem({
+          variables: {
+            modelId: currentModel.id,
+            schemaId: currentModel.metadataSchema.id,
+            fields: metaFields as ItemFieldInput[],
+          },
+        });
+        if (metaItem.errors || !metaItem.data?.createItem) {
+          Notification.error({ message: t("Failed to update item.") });
+          return;
+        }
+        const item = await updateItem({
+          variables: {
+            itemId: currentItem.id,
+            fields: currentItem.fields.map(field => ({
+              ...field,
+              value: field.value ?? "",
+            })) as ItemFieldInput[],
+            metadataId: metaItem?.data.createItem.item.id,
+            version: currentItem.version,
+          },
+        });
+        if (item.errors || !item.data?.updateItem) {
+          Notification.error({ message: t("Failed to update item.") });
+          return;
+        }
+      } else {
         Notification.error({ message: t("Failed to update item.") });
         return;
       }
       Notification.success({ message: t("Successfully updated Item!") });
     },
-    [updateItem, currentItem?.metadata?.version, t],
+    [createItem, currentItem, currentModel?.id, currentModel?.metadataSchema.id, t, updateItem],
   );
 
   const dateConvert = useCallback((value?: ItemValue) => {