5

I'm getting the error, "URL key for specified store already exists" when I try moving or adding products to a category in Magento 2 (Version 2.1). I have searched all over for a fix and even tried the fix here on Gihub but still I keep getting the error. The other problem even is that when I manually add or change a "URL Key" to make it work I still get the error.

Any help would be much appreciated.

5

We had a similar issue where we couldn't save categories and after much database searching and debugging I found the issue was when it updated the product url's for the category. We'd imported and deleted products previously but found out they still had entries in the url_rewrite table. So the request_path already existed.

To clear it out I had to run the query

delete from url_rewrite where entity_type='product' and entity_id NOT IN (Select entity_id from catalog_product_entity);

To check if you do have ghost records you can run

select count(*) from url_rewrite where entity_type='product' and entity_id NOT IN (Select entity_id from catalog_product_entity);

Good luck

| improve this answer | |
  • Thank so much @JasonWatt for the help! When I ran both commands I got the error, "#1146 - Table 'magnetodatabase.url_rewrite' doesn't exist". So I thought maybe I don't have a "url_rewrite" table. But when I checked with "select "url_rewrite" command the "url_rewrite" table came up. – P. Paul Aug 26 '16 at 17:42
  • Hi Paul Not sure where you're running the sql from but if it's on the command line try running use magnetodatabase first before the queries. Always test with the select query I sent first. – Jason Watt Aug 29 '16 at 23:40
  • Thanks for the help. I surely did run it later with the prefix and the queries worked. But the other problem was is that the first query didn't didn't delete anything according to the message. Then I used the second one to check for the ghost records and that one also stated no record found. In effect, the problem still exists. Thanks! – P. Paul Aug 31 '16 at 0:40
0

I have fixed this issue in more than 3-4 projects.

If you want to resolve this issue, you can upgrade your version with latest one or try below code logic:

Try this solution by overriding below function in your custom module :)

Path: vendor/magento/module-url-rewrite/Model/Storage

protected function doReplace(array $urls){ 
    $this->deleteOldUrls($urls); 
    $data = [];
    $storeId_requestPaths = [];
    foreach ($urls as $url) {
        $storeId = $url->getStoreId();
        $requestPath = $url->getRequestPath();
        $sql = "SELECT * FROM url_rewrite where store_id = $storeId and request_path = '$requestPath'";
        $exists = $this->connection->fetchOne($sql); 
        if ($exists) continue;
        $storeId_requestPaths[] = $storeId . '-' . $requestPath;
        $data[] = $url->toArray();
    }

    // Remove duplication data;
    $n = count($storeId_requestPaths);
    for ($i = 0; $i < $n - 1; $i++) {
        for ($j = $i + 1; $j < $n; $j++) {
            if ($storeId_requestPaths[$i] == $storeId_requestPaths[$j]) {
                unset($data[$j]);
            }
        }
    }
    try {
        $this->insertMultiple($data);
    } catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
        /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urlConflicted */
        $urlConflicted = [];
        foreach ($urls as $url) {
            $urlFound = $this->doFindOneByData(
                [
                    UrlRewriteData::REQUEST_PATH => $url->getRequestPath(),
                    UrlRewriteData::STORE_ID => $url->getStoreId(),
                ]
            );
            if (isset($urlFound[UrlRewriteData::URL_REWRITE_ID])) {
                $urlConflicted[$urlFound[UrlRewriteData::URL_REWRITE_ID]] = $url->toArray();
            }
        }
        if ($urlConflicted) {
            throw new \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException(
                __('URL key for specified store already exists.'),
                $e,
                $e->getCode(),
                $urlConflicted
            );
        } else {
            throw $e->getPrevious() ?: $e;
        }
    }

    return $urls;
}

Happy Coding :)

Thanks,

Ketan T.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.