Magento2: Cannot create a numeric value attribute option using the REST API

Created on 11 Sep 2018  路  15Comments  路  Source: magento/magento2

Preconditions


Magento ver. 2.2.5 using the REST API.

Steps to reproduce

  1. Make a POST call to http://winninge.nextmp.net/rest/V1/products/attributes//options i.e., http://winninge.nextmp.net/rest/V1/products/attributes/Size/options setting the label and value to be a numeric string, for example
    { "option": { "label": "30", "value": "30", "sort_order": 0, "is_default": false, "store_labels": [{ "store_id": 0, "label": "30" }] } }

Expected result

  1. Attribute option to be created successfully with a 200 status code

Actual result

  1. The API responds with { "message": "Cannot save attribute %1", "parameters": ["size"] } and a 400 status code

This is happening when the attribute is a number, and a number alone. It also happens with floating point numbers, such as 6.5.

Catalog Fixed in 2.2.x Fixed in 2.3.x Clear Description Confirmed Format is valid Ready for Work Reproduced on 2.2.x Reproduced on 2.3.x

Most helpful comment

To me it looks like this fix (https://github.com/magento/magento2/commit/3b9e96360e71b5d38167068b2b1a069ca97dc672) is trying to fix something that isn't broken.

Proof

  • If you provide value for option (which is the option ID, incremental ID of the option, by the way) in the POST request, \Magento\Eav\Model\ResourceModel\Entity\Attribute::_updateAttributeOption will make just update query and no new option will be created.
  • After that \Magento\Eav\Model\ResourceModel\Entity\Attribute::_updateAttributeOptionValues will be called and it tries to insert values for the option to eav_attribute_option_value table and that insert obviously fails due to foreign key constraint failure, because there is no parent option row in eav_attribute_option table.

Conclusion

Option value (option ID) should not be provided in the request when creating new options. If this is acceptable, then this fix should be just reverted. Otherwise, fix should be changed so that resource model allows to create new option with given option ID and this 'id_' prefix fix is removed.

All 15 comments

Hi @sidm. Thank you for your report.
To help us process this issue please make sure that you provided the following information:

  • [ ] Summary of the issue
  • [ ] Information on your environment
  • [ ] Steps to reproduce
  • [ ] Expected and actual results

Please make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, please, add a comment to the issue:

@magento-engcom-team give me {$VERSION} instance

where {$VERSION} is version tags (starting from 2.2.0+) or develop branches (2.2-develop +).
For more details, please, review the Magento Contributor Assistant documentation.

@sidm do you confirm that you was able to reproduce the issue on vanilla Magento instance following steps to reproduce?

  • [ ] yes
  • [ ] no

@magento-engcom-team give me 2.2.5 instance

Hi @sidm. Thank you for your request. I'm working on Magento 2.2.5 instance for you

Hi @sidm, here is your Magento instance.
Admin access: https://i-18009-2-2-5.engcom.dev.magento.com/admin
Login: admin Password: 123123q
Instance will be terminated in up to 3 hours.

Yes, I was able to reproduce this on the vanilla instance.

Reproduction of Issue on the Vanilla 2.2.5 instance

Steps:

  1. I created an attribute named Size
    image
  2. I added it to the default attribute set
    image
  3. I created a Bug Verify integration with "All" API permissions
    image
  4. Verified that the bug occurred using the same POST body as before, received the same error for this body
    {"option":{"label":"30","value":"30","sort_order":0,"is_default":false,"store_labels":[{"store_id":0,"label":"30"}]}}
    Response
    "{"message":"Cannot save attribute %1","parameters":["size"]}"
    with a status code 400
    image

Additional Verification

I also verified that the same call worked with a non-numeric value, using this body
{"option":{"label":"test","value":"test","sort_order":0,"is_default":false,"store_labels":[{"store_id":0,"label":"test"}]}} and received a 200 status code
image
you can see that the "test" attribute option now appears in the attribute
image

Hi @sidm , thank you for your report.
We've acknowledged the issue and added to our backlog.

Created PRs for 2.2 and 2.3.

Created PRs for 2.2 and 2.3.

Can you please link me to them?

@p-bystritsky

@sidm they are located in private Magento Engcom team repository.

@p-bystritsky Could you tell me what to change to fix this issue, or provide me with the code for the changed files?

Hi @sidm. Thank you for your report.
The issue has been fixed in magento-engcom/magento2ce#2158 by @p-bystritsky in 2.2-develop branch
Related commit(s):

The fix will be available with the upcoming 2.2.8 release.

Hi @sidm. Thank you for your report.
The issue has been fixed in magento-engcom/magento2ce#2159 by @p-bystritsky in 2.3-develop branch
Related commit(s):

The fix will be available with the upcoming 2.3.1 release.

Note that this change "breaks" the way \Magento\Eav\Model\Entity\Attribute\OptionManagement::add could be used to e.g. update options' store-specific labels, and now it always creates a new option in the database.
This is because \Magento\Eav\Model\ResourceModel\Entity\Attribute::_updateAttributeOption checks if the $optionId is numeric, and does an insert if it's not.

To me it looks like this fix (https://github.com/magento/magento2/commit/3b9e96360e71b5d38167068b2b1a069ca97dc672) is trying to fix something that isn't broken.

Proof

  • If you provide value for option (which is the option ID, incremental ID of the option, by the way) in the POST request, \Magento\Eav\Model\ResourceModel\Entity\Attribute::_updateAttributeOption will make just update query and no new option will be created.
  • After that \Magento\Eav\Model\ResourceModel\Entity\Attribute::_updateAttributeOptionValues will be called and it tries to insert values for the option to eav_attribute_option_value table and that insert obviously fails due to foreign key constraint failure, because there is no parent option row in eav_attribute_option table.

Conclusion

Option value (option ID) should not be provided in the request when creating new options. If this is acceptable, then this fix should be just reverted. Otherwise, fix should be changed so that resource model allows to create new option with given option ID and this 'id_' prefix fix is removed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xi-ao picture xi-ao  路  3Comments

denis-g picture denis-g  路  3Comments

jzalenski picture jzalenski  路  3Comments

andreaskoch picture andreaskoch  路  3Comments

ostmond picture ostmond  路  3Comments