{"record":{"id":"757b0a4ddb1c8217","repo":"juspay/hyperswitch","slug":"expecting-valid-response-but-got-an-error-response","errorCode":null,"errorMessage":"Expecting valid response but got an error response","messagePattern":"Expecting valid response but got an error response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cypress-tests/cypress/e2e/configs/Payment/Utils.js","lineNumber":341,"sourceCode":"    typeof resData.body.error_message !== \"undefined\"\n  ) {\n    return false;\n  } else {\n    return true;\n  }\n};\n\nexport function defaultErrorHandler(response, response_data) {\n  if (\n    response.status === 400 &&\n    response.body.error.message === \"Payment method type not supported\"\n  ) {\n    // Update the default status from 501 to 400 as `unsupported payment method` error is the next common error after `not implemented` error\n    response_data = updateDefaultStatusCode();\n  }\n\n  if (response_data.status === 200) {\n    throw new Error(\"Expecting valid response but got an error response\");\n  }\n\n  expect(response.body).to.have.property(\"error\");\n\n  if (typeof response.body.error === \"object\") {\n    for (const key in response_data.body.error) {\n      // Check if the error message is a Json deserialize error\n      const apiResponseContent = response.body.error[key];\n      const expectedContent = response_data.body.error[key];\n      if (\n        typeof apiResponseContent === \"string\" &&\n        apiResponseContent.includes(\"Json deserialize error\")\n      ) {\n        expect(apiResponseContent).to.include(expectedContent);\n      } else {\n        expect(apiResponseContent).to.equal(expectedContent);\n      }\n    }","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/juspay/hyperswitch/blob/9b8b89dc378b62c9a6feda647bad4719d2de7699/cypress-tests/cypress/e2e/configs/Payment/Utils.js#L323-L359","documentation":"Thrown by defaultErrorHandler in cypress-tests/cypress/e2e/configs/Payment/Utils.js when the API answered with an error body but the test's expected response_data.status is 200 — i.e. the spec asserted success and the connector errored. (For 'Payment method type not supported' 400s it first rewrites the expected status via updateDefaultStatusCode().)","triggerScenarios":"A payment/conf spec configured with response_data.status = 200 hits a real error: connector credentials invalid, payment method disabled for the merchant, amount/currency rejected, or a 501 'not implemented' — expect(response.body).to.have.property('error') context shows the actual error, but this throw fires first because 200 was expected.","commonSituations":"Test matrix runs a connector that does not support the spec's payment method; sandbox connector keys rotated/expired; a regression that broke a previously-green flow; expected-status fixture not updated after connector behaviour changed.","solutions":["Read the actual API error (response.body.error) in the Cypress command log / network tab to identify the real cause","If the connector legitimately cannot succeed for this case, update the spec's response_data.status to the actual expected code instead of 200","Verify merchant/connector config: API keys valid, payment method enabled, correct capture_method/amount","Exclude the connector from this spec via its connector exclusion list when the flow is unsupported by design"],"exampleFix":"// before (spec expects success but connector declines)\nconst defaultResponse = { status: 200, body: { ... } };\n\n// after (expect the realistic decline for this connector)\nconst defaultResponse = {\n  status: 400,\n  body: { error: { message: 'Payment method type not supported' } },\n};","handlingStrategy":"validation","validationCode":"// Align expected status with the connector's real capability before the call\nconst NOT_IMPLEMENTED_CONNECTORS = new Set(['connector_x' /* ... */]);\nif (NOT_IMPLEMENTED_CONNECTORS.has(connectorId) || !supportsPaymentMethod(connectorId, paymentMethodType)) {\n  response_data = { ...response_data, status: 501, body: { error: { message: 'Not Implemented' } } };\n}","typeGuard":null,"tryCatchPattern":"// In the spec: distinguish 'expected-success-but-errored' from real regressions\ncy.get('@postCall').then((response) => {\n  try {\n    defaultErrorHandler(response, response_data);\n  } catch (e) {\n    if (String(e.message).includes('Expecting valid response but got an error response')) {\n      // connector declined/unsupported: inspect response.body.error and update config or skip\n      cy.log(`Connector error: ${JSON.stringify(response.body.error)}`);\n      this.skip();\n    } else {\n      throw e;\n    }\n  }\n});","preventionTips":["Keep per-connector expected-status fixtures instead of assuming 200 everywhere","Inspect response.body.error in the failure — it names the actual decline reason","Exclude connectors that structurally cannot pass a spec via the spec's connector exclusion list"],"tags":["cypress","e2e","assertion","connector","payment"],"backgroundTag":null,"analyzedSha":"9b8b89dc378b62c9a6feda647bad4719d2de7699","analyzedAt":"2026-08-16T09:01:53.433Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}