diff --git a/vendor/magento/module-catalog/Model/ResourceModel/Category.php b/vendor/magento/module-catalog/Model/ResourceModel/Category.php
index 88dbed6..b853ba1 100644
--- a/vendor/magento/module-catalog/Model/ResourceModel/Category.php
+++ b/vendor/magento/module-catalog/Model/ResourceModel/Category.php
@@ -20,6 +20,7 @@ use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DataObject;
 use Magento\Framework\EntityManager\EntityManager;
 use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
 
 /**
@@ -657,7 +658,9 @@ class Category extends AbstractResource implements ResetAfterRequestInterface
         $entityIdsFilterHash = md5($serializeData);
         // @codingStandardsIgnoreEnd
 
-        if (!isset($this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attribute->getId()][$expectedValue])) {
+        $attributeId = $attribute->getId() ?? '';
+
+        if (!isset($this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attributeId][$expectedValue])) {
             $linkField = $this->getLinkField();
             $bind = ['attribute_id' => $attribute->getId(), 'value' => $expectedValue];
             $selectEntities = $this->getConnection()->select()->from(
@@ -674,11 +677,11 @@ class Category extends AbstractResource implements ResetAfterRequestInterface
                 $entityIdsFilter,
                 \Zend_Db::INT_TYPE
             );
-            $this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attribute->getId()][$expectedValue] =
+            $this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attributeId][$expectedValue] =
                 $this->getConnection()->fetchCol($selectEntities, $bind);
         }
 
-        return $this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attribute->getId()][$expectedValue];
+        return $this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attributeId][$expectedValue];
     }
 
     /**
@@ -1020,6 +1023,29 @@ class Category extends AbstractResource implements ResetAfterRequestInterface
         return $this;
     }
 
+    /**
+     * @inheritDoc
+     */
+    public function validate($object)
+    {
+        $errors = parent::validate($object);
+        $currentId = $object->getId();
+        $newParentId = $object->getParentId();
+        if ($parentPath = $this->getCategoryPathById($newParentId)) {
+            $parentPathIds = explode("/", $parentPath);
+        } else {
+             $parentPathIds = [];
+        }
+
+        if ($currentId && !empty($parentPathIds) && in_array($currentId, $parentPathIds)) {
+            throw new LocalizedException(
+                __('A category cannot be assigned to one of its own descendants.')
+            );
+        }
+
+        return $errors;
+    }
+
     /**
      * Process positions of old parent category children and new parent category children.
      *
diff --git a/vendor/magento/module-catalog/i18n/en_US.csv b/vendor/magento/module-catalog/i18n/en_US.csv
index fc899f4..bcff430 100644
--- a/vendor/magento/module-catalog/i18n/en_US.csv
+++ b/vendor/magento/module-catalog/i18n/en_US.csv
@@ -869,3 +869,4 @@ Details,Details
 "Learn more","Learn more"
 "Recently Viewed","Recently Viewed"
 "Could not acquire lock for SKU %1","Could not acquire lock for SKU %1"
+"A category cannot be assigned to one of its own descendants.","A category cannot be assigned to one of its own descendants."
