Turns out it was an external job running from cron. We created a script to remove special pricing from products. The problem was that the script was not loading the entire product object. When it removed the pricing and saved the product the url_key was removed as well.
The job grabs a collection of all the products with expired special pricing. First I removed the addAttributeToSelect from the collection, but that didn't work and I'm not fully sure why. So my end solution was to loop through each product in the collection and use the id to load the individual product again, makes the changes and save.
If anyone comes upon this keep in mind that it comes down to a product being modified and saved so look into all the places you are doing that in your custom modules or scripts.
I spend lot of time to understand ... I had same problem. On development my java application, using official API, first i create product with one (main image), after I trying to add more images with Your error.
Solution is VERY SIMPLE. When You add more than one image, avoid to add ID in json call. (I have my own Java model which reproduce original API and NEVER use "int" => use "Integer" instead, for all keys at model)
BAD:
{
"entry": {
"id": 0,
"mediaType": "image",
"position": 0,
"disabled": false,
"types": ["image", "small_image", "thumbnail"],
"content":{
"base64_encoded_data" : "_9j_4AAQSkZJRgABAQEAYABgAAD__...<cutted_here>",
"type": "image/jpeg",
"name":"pic_name.jpg"
}
}
}
Right way:
{
"entry": {
"mediaType": "image",
"position": 0,
"disabled": false,
"types": ["image", "small_image", "thumbnail"],
"content":{
"base64_encoded_data" : "_9j_4AAQSkZJRgABAQEAYABgAAD__...<cutted_here>",
"type": "image/jpeg",
"name":"pic_name.jpg"
}
}
}
When You read official documentation is NO describe to right way. I've founded solution looking here:
line 509, see : if (isset($entry['id']))
at ./vendor/magento/module-catalog/Model/ProductRepository.php
PHP is looking if ID is set !!!
Alberto
Best Answer
Although Swagger doesn't specify "url_key", you can add this attribute value by the following method:
Note: Next time, you can use GET to know the product JSON structure first. Then any customized attributes can be created according to the JSON structure.