{"id":19029043,"date":"2026-09-25T08:15:02","date_gmt":"2026-09-25T08:15:02","guid":{"rendered":"https:\/\/wordpress.org\/support\/topic\/non-user-friendly-error-message\/"},"modified":"2026-09-25T08:15:02","modified_gmt":"2026-09-25T08:15:02","slug":"non-user-friendly-error-message","status":"publish","type":"topic","link":"https:\/\/wordpress.org\/support\/topic\/non-user-friendly-error-message\/","title":{"rendered":"Non user friendly error message"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">When in test mode on Woopayments and going into My Account &gt; Add Payment method and adding the info of card number &#8216;0000 0000 0000 0000&#8217;, any valid expiry, any security code, and any country &#8211; you get the error &#8220;Cannot destructure property &#8216;id&#8217; of &#8216;undefined&#8217; as it is undefined.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Can this be made more user friendly?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From researching the error comes from in <code>plugins\/woocommerce-payments\/dist\/checkout.js<\/code>, submitting the add-payment-method form does this (de-minified):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const result = await stripe.createPaymentMethod({ elements, params });\n\nif (result.error) {\n    \/\/ Save Stripe's error details as hidden inputs on the form\n    appendErrorInputs(form, result.error);\n} else {\n    appendPaymentMethodInput(form, result.paymentMethod.id);\n}\n\n\/\/ ...but then carries on regardless of the error\nawait afterCreate(result.paymentMethod, form, api);   \/\/ paymentMethod is undefined\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On the add-payment-method page, <code>afterCreate<\/code> is this function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const wt = ({ id }, form, api) =&gt; api.setupIntent(id, ...)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When Stripe rejects the card, <code>result.paymentMethod<\/code> is <code>undefined<\/code>. Destructuring <code>{ id }<\/code> from it throws a <code>TypeError<\/code>. The <code>catch<\/code> block then shows that raw JavaScript message (<code>e.message<\/code>) to the user.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At checkout, the same code works because the step after the error does nothing. The form submits, and the server turns the hidden error fields into a proper message. The add-payment-method page runs the setup intent step in the browser, so it crashes first. Stripe&#8217;s real, friendly message is sitting in a hidden <code>#wcpay-payment-method-error-message<\/code> input that nothing reads.<\/p>\n","protected":false},"template":"","class_list":["post-19029043","topic","type-topic","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19029043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic"}],"about":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/types\/topic"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19029043\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/media?parent=19029043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}