Sitemap Generation Issue - URLBuilder - must be type of string - error

As I’m pushing to go live, I have run in to a little road block. I’m trying to tie up some loose ends, however this one has me stumped. Any tips on troubleshooting? This is from the php logs and there is nothing generated in the exception or sys logs when generate this issue.

I’m simply trying to generate a sitemap.xml in the admin area and this is the error I get. I’m on 2.3.5-p1. I have never tried to generate a sitemap up until now. I am using mageworx seo extension, but even with that disabled I still get the same results and they said it is my issue and not their extension, so they aren’t willing to help. Go figure. I expect this has something to do with the M1–>M2 migration process.

AH01071: Got error 'PHP message: PHP Fatal error:
Uncaught TypeError: Argument 1 passed to Magento\\Catalog\\Model\\Product\\Image\\UrlBuilder::getUrl() must be of the type string, null given, called in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/mageworx/module-xmlsitemap/Model/ResourceModel/Catalog/Product.php on line 527 and defined in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-catalog/Model/Product/Image/UrlBuilder.php:65\nStack trace:\n
#0 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/mageworx/module-xmlsitemap/Model/ResourceModel/Catalog/Product.php(527): Magento\\Catalog\\Model\\Product\\Image\\UrlBuilder->getUrl(NULL, 'product_page_im...')\n
#1 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/mageworx/module-xmlsitemap/Model/ResourceModel/Catalog/Product.php(480): MageWorx\\XmlSitemap\\Model\\ResourceModel\\Catalog\\Product->getProductImageUrl(NULL)\n
#2 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/mageworx/module- xmlsitemap/Model/ResourceModel/C...\n', referer:

Any ideas, tips, or suggestions would be amazing. I’m not sure how to narrow this down further from this point to see if it is a particular product that has an image/string issue or if it is all of them. There are no issues on the frontend with the images and they are all there as one would expect.

You’ve kind of stumped me too. The only leads suggest it is a MageWorx issue from the log. Have you tried recompiling both:

  1. Whilst the module is enabled (to try and clear the issue)
  2. After disabling it (to ensure the disabled changes take affect)?

It’s entirely possible there’s just a “ghost in the machine” from dodgy caching or old compiling that could cause this error if MageWorx insist it’s not an issue of theirs. Also, I assume this module is compatible with M2.3.5?

I’ll go back and c:c, reindex, recompile, deploy-static content. Pretty sure that covers everything. They need a command that just does everything.

Did all the above with and without the module(s) from mageworx enabled. I still received the same sitemap generation error, but without “mageworx” in the error.

AH01071: Got error 'PHP message: PHP Fatal error: Uncaught TypeError: Argument 1 passed to Magento\\Catalog\\Model\\Product\\Image\\UrlBuilder::getUrl() must be of the type string, null given, called in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-sitemap/Model/ResourceModel/Catalog/Product.php on line 492 and defined in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-catalog/Model/Product/Image/UrlBuilder.php:65\nStack trace:\n
#0 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-sitemap/Model/ResourceModel/Catalog/Product.php(492): Magento\\Catalog\\Model\\Product\\Image\\UrlBuilder->getUrl(NULL, 'product_page_im...')\n
#1 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-sitemap/Model/ResourceModel/Catalog/Product.php(450): Magento\\Sitemap\\Model\\ResourceModel\\Catalog\\Product->getProductImageUrl(NULL)\n
#2 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-sitemap/Model/ResourceModel/Catalog/Product.php(4...\n',` 

There is a setting in the back of magento that says to include images or not in the sitemap. I changed this to no and it generated without issues on the default magento sitemap generation.

I did try on Mageworx, but it could have been a cache or something that needed cleared or maybe they are still incorporating images somewhere despite what that setting says. It is definitely the images.

Where to go from here? It appears maybe some of the log is truncated, so I’m going to try and pull the actual php log off the system. Time to go look that up and see where it is.

Line 450 about in product.php

protected function _getAllProductImages($product, $storeId)
    {
        $product->setStoreId($storeId);
        $gallery = $this->mediaGalleryResourceModel->loadProductGalleryByAttributeId(
            $product,
            $this->mediaGalleryReadHandler->getAttribute()->getId()
        );

        $imagesCollection = [];
        if ($gallery) {
            foreach ($gallery as $image) {
                $imagesCollection[] = new \Magento\Framework\DataObject(
                    [
                        'url' => $this->getProductImageUrl($image['file']),
                        'caption' => $image['label'] ? $image['label'] : $image['label_default'],
                    ]
                );
            }
        }

        return $imagesCollection;
    }

Product.php 492

         private function getProductImageUrl($image)
            {
                return $this->imageUrlBuilder->getUrl($image, 'product_page_image_large');
            }

URLbuilder.php line 65

public function getUrl(string $baseFilePath, string $imageDisplayArea): string
    {
        $imageArguments = $this->presentationConfig->getViewConfig()->getMediaAttributes(
            'Magento_Catalog',
            Image::MEDIA_TYPE_CONFIG_NODE,
            $imageDisplayArea
        );

        $imageMiscParams = $this->imageParamsBuilder->build($imageArguments);

        if ($baseFilePath === null || $baseFilePath === 'no_selection') {
            $asset = $this->placeholderFactory->create(
                [
                    'type' => $imageMiscParams['image_type']
                ]
            );
        } else {
$asset = $this->viewAssetImageFactory->create(
                [
                    'miscParams' => $imageMiscParams,
                    'filePath' => $baseFilePath,
                ]
            );
        }

        return $asset->getUrl();
    }
}

Sorry for all the posts. It helps me think aloud and keep track of what the heck I’m doing and hopefully may help someone out there at the same time.

I’m thinking maybe it is possible that the type is set incorrectly in the DB for the table it is getting the image URLs from???

1 Like

Just putting this little gem of an article here: https://blog.magepsycho.com/how-to-fix-the-issue-product-images-missing-in-backend-but-not-in-frontend/#more-643

This could very well be the issue.

Nothing in debug.log either. This is a tough one.

Is this table: catalog_product_entity_media_gallery

suppose to have varchar(255) NULL with no default value?

I am running the following command in hopes that it generates everything the way M2 would like as far as all of the types of images, locations in db, locations on the server etc…

bin/magento catalog:images:resize

I think it will take all night to run. We will see in the morning.

Yes. Here is a screenshot of a vanilla database
catalog_product_entity_media_gallery

Good spot!

You can string commands together in SSH by using “&&”. So, an example of this might look like:

Before

rm -rf var/cache/* var/page_cache/* generated/code/*
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy en_US en_GB -f
bin/magento indexer:reindex
bin/magento cache:clean
bin/magento cache:flush

After

rm -rf var/cache/* var/page_cache/* generated/code/* && bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento setup:static-content:deploy en_US en_GB -f && bin/magento indexer:reindex && bin/magento cache:clean && bin/magento cache:flush

Thanks for the info! I tried to string all of the magento commands to clearing things once and it ended up throwing a fit.

Thanks for the screenshot. I’ll be checking that now.

The resize command ran last night, however it only got to about 20% and then it threw a similar error.

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Symfony\Component\Console\Helper\ProgressBar::setMessage() must be of the type string, null given, called in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-media-storage/Console/Command/ImagesResizeCommand.php on line 107 and defined in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/symfony/console/Helper/ProgressBar.php:151
Stack trace:
#0 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/module-media-storage/Console/Command/ImagesResizeCommand.php(107): Symfony\Component\Console\Helper\ProgressBar->setMessage(NULL)
#1 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/symfony/console/Command/Command.php(255): Magento\MediaStorage\Console\Command\ImagesResizeCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/magento/framework/Interception/Interceptor.php(58): Sym in /home/363882.cloudwaysapps.com/qzzbnfgmbr/public_html/vendor/symfony/console/Helper/ProgressBar.php on line 151

so… my db manager is a little different than phpmyadmin in cloudways. I’m not sure why they did that, but it must be more efficient or easier to manage for them. I see that there is no default value given in my DB for that table.

I’m not certain, but does NULL being checked mean that NULL is the default value if there is nothing provided? or does a default value have to be provided as well. That is the only discrepency I can see between the two screenshots.

Regardless, the errors is stating NULL is given and is not of type string. There has to be some sort of disconnect in the DB for the image values. Magento, it’s great until it isn’t. haha

Still no progress other than eliminating options to try. I restored back to a 2.3.3 install just to eliminate that it was something in the upgarde to 2.3.5-p1. Still the same result. I restored back to my current state.

I can say that the cloudways backup/restore functionality works well. haha.

I also tried this: https://github.com/Vendic/EAVCleaner

I was hoping there were just some cobwebs in the database that it would clean out. There certainly were things that could be cleaned/removed, but it had no effect on the issue. With that said. I’m back out of ideas. I wish I could step through the code, but I think you can only do that with PHPStorm setup with it.

I think I’ve found a way to get through this. I don’t know the actual issue or how to resolve it, but I think that there are just a few images that are causing this problem.

I don’t want to delete them directly out of media/catalog/product because then the db won’t be updated. How can I find which product is using a particular image. Yes they are name, but I want to make sure I pinpoint this as I’m running

bin/magento catalog:images:resize

and it takes quite a while each time I run it. At this point, if this is the solution and I have to run it 10 times, I am completely fine with that. I got about 20% through and it hit the same image twice and stopped.

Locating all of the products using that one single image, I went to try to delete them and get this error:
The image cannot be removed as it has been assigned to the other image role
which leads me here:

I am going down a rabbit hole here, hopefully the other side is my sitemap generated.

Is there a way I can run the following command, but not actually have it make changes?

bin/magento catalog:images:resize

I tried appending --dry-run, but I think it is deprecated. :frowning:

Correct

Was this a site-migration from M1 to M2 by any chance?

I don’t think there’s an easy way without data mining through the database.

It seems like you have an old/rogue attribute that may have been removed but didn’t clean up the database correctly - Or something along those lines.

I checked and there doesn’t appear to be any Dry Run or Verbose mode.

Have you been able to differentiate between a Product you can remove and a product you cannot remove? Knowing this might help identify what to look for in the database tables. This is what I would do…

  1. Get the filename.jpg of both versions (write them down somewhere).
  2. Search records (value) for working version in catalog_product_entity_varchar
  3. Search records (value) for broken version in catalog_product_entity_varchar
  4. Compare both sets of results

You might find that the “broken” result has an extra row that relates to an old attribute_id. I think by default there are 3 results for each search (image, small image and thumbnail).

This screenshot is 2 default results (don’t compare to mine, as IDs will be different).
compare