{"record":{"id":"c8f9aed7560a29ca","repo":"juspay/hyperswitch","slug":"expected-no-deny-action-for-non-blocklisted-card","errorCode":null,"errorMessage":"Expected no deny action for non-blocklisted card","messagePattern":"Expected no deny action for non-blocklisted card","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cypress-tests/cypress/support/commands.js","lineNumber":7829,"sourceCode":"            .to.have.property(\"payment_id\")\n            .to.equal(paymentId);\n\n          // Check for expected response structure based on test case\n          if (resData.body.sdk_next_action?.next_action?.deny) {\n            expect(response.body).to.have.property(\"sdk_next_action\");\n            expect(response.body.sdk_next_action).to.have.property(\n              \"next_action\"\n            );\n            expect(response.body.sdk_next_action.next_action).to.have.property(\n              \"deny\"\n            );\n            expect(response.body.sdk_next_action.next_action.deny)\n              .to.have.property(\"message\")\n              .to.equal(resData.body.sdk_next_action.next_action.deny.message);\n          } else {\n            // For non-blocklisted cards, we expect no deny action\n            if (response.body.sdk_next_action?.next_action?.deny) {\n              throw new Error(\n                \"Expected no deny action for non-blocklisted card\"\n              );\n            }\n          }\n        } else {\n          throw new Error(\n            `Eligibility check failed with status: ${response.status} and message: ${response.body?.error?.message}`\n          );\n        }\n      });\n    });\n  }\n);\n\n// DDC Race Condition Test Commands\nCypress.Commands.add(\n  \"ddcServerSideRaceConditionTest\",\n  (confirmData, globalState) => {","sourceCodeStart":7811,"sourceCodeEnd":7847,"githubUrl":"https://github.com/juspay/hyperswitch/blob/9b8b89dc378b62c9a6feda647bad4719d2de7699/cypress-tests/cypress/support/commands.js#L7811-L7847","documentation":"Thrown by paymentsEligibilityCheck when POST /payments/{paymentId}/eligibility returns 200 but the response contains sdk_next_action.next_action.deny while the fixture Response does not expect one. The command treats presence of a deny action for a supposedly non-blocklisted card as a test failure (blocklist leaking onto clean cards).","triggerScenarios":"The card used in the eligibility check matches a blocklist rule left over from an earlier test/spec (overlapping BIN); server-side false positive denying a clean card; fixture Response block missing the deny structure while the connector legitimately returns one.","commonSituations":"Shared test card BINs across specs with rules created in one spec still active during another; parallelized specs racing blocklist create/delete; expected-deny fixtures written without the sdk_next_action.next_action.deny node.","solutions":["Clean up blocklist rules in an after() hook (cy.blocklistDeleteRule) for every spec that creates them","Use distinct card BINs for deny and allow eligibility tests to avoid rule overlap","If the connector legitimately denies, add sdk_next_action.next_action.deny.message to the fixture Response","Verify via GET /blocklist that no unexpected rule covers the card being tested"],"exampleFix":"// before\nafter(() => {\n  // no cleanup → stale card_bin rule denies later specs\n});\n// after\nafter(() => {\n  cy.blocklistDeleteRule('card_bin', blocklistedBin, globalState);\n});","handlingStrategy":"validation","validationCode":"// precondition: no lingering rules should cover the card under test\nconst cardBin = body.payment_method_data.card_number.slice(0, 6);\ncy.request({\n  method: 'GET',\n  url: `${globalState.get('baseUrl')}/blocklist?data_kind=card_bin`,\n  headers: { 'api-key': globalState.get('apiKey') },\n  failOnStatusCode: false,\n}).then((res) => {\n  const covered = res.status === 200 && JSON.stringify(res.body).includes(cardBin);\n  expect(covered, 'no stale blocklist rule covers this card').to.be.false;\n});","typeGuard":"const hasDenyAction = (b) =>\n  Boolean(b?.sdk_next_action?.next_action?.deny);","tryCatchPattern":null,"preventionTips":["Use disjoint card BINs for deny vs allow eligibility tests","Delete blocklist rules in after() hooks in the same spec that created them","Keep deny-expectation fixtures explicit by including sdk_next_action.next_action.deny.message"],"tags":["cypress","blocklist","eligibility","test-isolation","assertion"],"backgroundTag":null,"analyzedSha":"9b8b89dc378b62c9a6feda647bad4719d2de7699","analyzedAt":"2026-08-16T09:01:53.433Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}