{"record":{"id":"47f74b7cc272fee6","repo":"juspay/hyperswitch","slug":"payment-method-create-failed-with-status-respons","errorCode":null,"errorMessage":"Payment method create failed with status ${response.status}: ${JSON.stringify(response.body)}","messagePattern":"Payment method create failed with status (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cypress-tests/cypress/support/commands.js","lineNumber":8375,"sourceCode":"    failOnStatusCode: false,\n  }).then((response) => {\n    if (response.status === 200) {\n      globalState.set(\"paymentMethodId\", response.body.id);\n      expect(requestBody.customer_id, \"customer_id\").to.equal(\n        response.body.customer_id\n      );\n      expect(requestBody.payment_method_type, \"payment_method_type\").to.equal(\n        response.body.payment_method_type\n      );\n      expect(\n        requestBody.payment_method_subtype,\n        \"payment_method_subtype\"\n      ).to.equal(response.body.payment_method_subtype);\n      expect(requestBody.storage_type, \"storage_type\").to.equal(\n        response.body.storage_type\n      );\n    } else {\n      throw new Error(\n        `Payment method create failed with status ${response.status}: ${JSON.stringify(response.body)}`\n      );\n    }\n  });\n});\n\nCypress.Commands.add(\"getRawPaymentMethodDetailsCall\", (globalState) => {\n  const apiKey = globalState.get(\"apiKey\");\n  const profileId = globalState.get(\"profileId\");\n  const paymentMethodId = globalState.get(\"paymentMethodId\");\n\n  cy.request({\n    method: \"GET\",\n    url: `${globalState.get(\"pmServiceUrl\")}/v1/payment-methods/${paymentMethodId}?fetch_raw_detail=true`,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      Accept: \"application/json\",\n      \"X-Profile-Id\": profileId,","sourceCodeStart":8357,"sourceCodeEnd":8393,"githubUrl":"https://github.com/juspay/hyperswitch/blob/9b8b89dc378b62c9a6feda647bad4719d2de7699/cypress-tests/cypress/support/commands.js#L8357-L8393","documentation":"Thrown by the paymentMethodCreateCall (v2, port 8082) custom Cypress command: on success it asserts that payment_method_type, payment_method_subtype, and storage_type echo back from the response; any status outside the success branch hits the else-throw, which embeds both the status and JSON.stringify(response.body). Because the full body is included, the message is self-describing — it usually contains the server's validation error verbatim.","triggerScenarios":"400 when pmData is missing/invalid payment_method_type, payment_method_subtype, or storage_type; 401 with a bad apiKey; 404 when the endpoint path is wrong or the referenced customer/profile does not exist; 422/400 when the customerId in globalState was never set (earlier customerCreateCall failed or was skipped, leaving paymentMethodId/customerId undefined); 5xx from the v2 service.","commonSituations":"Test-ordering dependency: this command runs before customerCreateCall populated globalState, so the request targets a missing customer; using v1 credentials/base URL (8081) against the v2 service (8082); connector schema change renaming subtypes; expired API key in the environment; data cleanup between runs deleting the customer the test assumed existed.","solutions":["Read the JSON body in the thrown message first — it contains the server's exact validation message; fix the named pmData field.","Assert prerequisites before the call: globalState has apiKey, profileId, and customerId set (i.e. the customer-create step actually ran and succeeded).","401 -> refresh the API key; 404 -> confirm the v2 base URL/port (8082) and that the customer still exists in that environment.","If a renamed payment_method_type/subtype/storage_type value: update the fixture to the current v2 enum values.","429/5xx -> retry after the service is healthy."],"exampleFix":"// before: runs even when the customer step failed, producing an opaque 404\ncy.paymentMethodCreateCall(globalState, pmData);\n\n// after: fail fast with a clear cause when state is missing\nconst customerId = globalState.get('customerId');\nif (!customerId) {\n  throw new Error('paymentMethodCreateCall: customerId missing in globalState — run customerCreateCall first');\n}\ncy.paymentMethodCreateCall(globalState, pmData);","handlingStrategy":"validation","validationCode":"// Run before paymentMethodCreateCall\nfunction validatePaymentMethodCreateCall(globalState, pmData) {\n  for (const key of ['apiKey', 'profileId', 'customerId']) {\n    if (!globalState.get(key)) throw new Error(`paymentMethodCreateCall: ${key} missing in globalState — earlier step failed or skipped`);\n  }\n  for (const field of ['payment_method_type', 'payment_method_subtype', 'storage_type']) {\n    if (!pmData?.[field]) throw new Error(`paymentMethodCreateCall: pmData.${field} is required`);\n  }\n}","typeGuard":"// Narrow the response before asserting the echo fields, so a 4xx body never reaches .to.equal()\nfunction isPaymentMethodCreated(body) {\n  return (\n    typeof body === 'object' &&\n    body !== null &&\n    typeof body.payment_method_type === 'string' &&\n    typeof body.payment_method_subtype === 'string' &&\n    typeof body.storage_type === 'string'\n  );\n}","tryCatchPattern":"// The thrown message already carries status + full JSON body; extract them for routing:\n// try { ... } catch (e) {\n//   const m = e.message.match(/status (\\d+): (.*)$/s);\n//   if (!m) throw e;\n//   const [, statusStr, bodyJson] = m;\n//   const status = Number(statusStr);\n//   const body = JSON.parse(bodyJson);\n//   if (status === 400) throw new Error(`fix pmData: ${body.error?.message}`);\n//   if (status === 401) throw new Error('refresh apiKey');\n//   if (status === 404) throw new Error('wrong v2 base URL/port or customer missing');\n//   throw e;\n// }","preventionTips":["Chain test steps explicitly: customerCreateCall must succeed before paymentMethodCreateCall; assert customerId exists in globalState first.","Fail fast with a clear precondition error instead of letting a missing customerId produce an opaque 404.","Use the v2 credentials and base URL (port 8082) for v2 commands — never mix with v1 (8081).","After server upgrades, re-verify the enum values for payment_method_type/subtype/storage_type in fixtures.","Keep response bodies in thrown messages (JSON.stringify) — they are the fastest diagnostic you have."],"tags":["api","payment-methods","cypress","validation","test-ordering"],"backgroundTag":null,"analyzedSha":"9b8b89dc378b62c9a6feda647bad4719d2de7699","analyzedAt":"2026-08-16T09:01:53.433Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}