{"record":{"id":"72e6f578e5c76918","repo":"juspay/hyperswitch","slug":"no-token-received-from-login","errorCode":null,"errorMessage":"No token received from login","messagePattern":"No token received from login","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cypress-tests/cypress/support/commands.js","lineNumber":6871,"sourceCode":"    method: \"POST\",\n    url: url,\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n    body: signinBody,\n    failOnStatusCode: false,\n  }).then((response) => {\n    logRequestId(response.headers[\"x-request-id\"]);\n\n    cy.wrap(response).then(() => {\n      if (response.status === 200) {\n        if (response.body.token_type === \"totp\") {\n          expect(response.body, \"totp_token\").to.have.property(\"token\").and.to\n            .not.be.empty;\n\n          const totpToken = response.body.token;\n          if (!totpToken) {\n            throw new Error(\"No token received from login\");\n          }\n          globalState.set(\"totpToken\", totpToken);\n        }\n      } else {\n        throw new Error(\n          `User login call failed to get totp token with status: \"${response.status}\" and message: \"${response.body.error.message}\"`\n        );\n      }\n    });\n  });\n});\nCypress.Commands.add(\"terminate2Fa\", (globalState) => {\n  // Define the necessary variables and constant\n  const baseUrl = globalState.get(\"baseUrl\");\n  const queryParams = `skip_two_factor_auth=true`;\n  const apiKey = globalState.get(\"totpToken\");\n  const url = `${baseUrl}/user/2fa/terminate?${queryParams}`;\n","sourceCodeStart":6853,"sourceCodeEnd":6889,"githubUrl":"https://github.com/juspay/hyperswitch/blob/9b8b89dc378b62c9a6feda647bad4719d2de7699/cypress-tests/cypress/support/commands.js#L6853-L6889","documentation":"Thrown by the userLogin command when POST /user/v2/signin?token_only=true returns 200 with token_type 'totp' but the token field is falsy. Note the chai assertion directly above already requires a non-empty 'token' property, so in practice that expect fails first with its own message; this throw is a defensive fallback for edge cases (e.g. non-string falsy token).","triggerScenarios":"Signin returns HTTP 200, token_type === 'totp', but body.token is '', null, or undefined — the preceding expect(...).to.not.be.empty normally raises a chai error before this line executes.","commonSituations":"Server bug returning 200 with an empty token; response shape change (token moved/nested); mocking/proxy stripping the token field in local environments.","solutions":["Print the full signin response body (cy.log(JSON.stringify(response.body))) to see what token was actually returned","Verify the token_only=true query param is reaching the server and the signin endpoint version (/user/v2/signin) matches the server","If the token field moved or was renamed, update both the chai expect and the read in commands.js"],"exampleFix":"// before\nconst totpToken = response.body.token;\nif (!totpToken) throw new Error('No token received from login');\n// after\nconst totpToken = response.body.token;\nif (!totpToken)\n  throw new Error(\n    `No token received from login: ${JSON.stringify(response.body)}`\n  );","handlingStrategy":"validation","validationCode":"// sanity-check the signin contract before relying on the token\nconst body = response.body;\nif (body.token_type === 'totp') {\n  expect(typeof body.token).to.equal('string');\n  expect(body.token.length).to.be.greaterThan(0);\n}","typeGuard":"const hasNonEmptyToken = (b) =>\n  b != null && typeof b.token === 'string' && b.token.length > 0;","tryCatchPattern":"try {\n  await cy.userLogin(globalState);\n} catch (e) {\n  if (/No token received from login/.test(e.message)) {\n    // inspect full signin response; likely env/server issue, not test logic\n    throw new Error(`signin returned empty token — check server logs`);\n  }\n  throw e;\n}","preventionTips":["Keep the chai non-empty expect and the falsy check aligned (both read response.body.token)","On failure, dump the whole response body via cy.log(JSON.stringify(...)) before debugging credentials"],"tags":["cypress","auth","signin","totp","token"],"backgroundTag":null,"analyzedSha":"9b8b89dc378b62c9a6feda647bad4719d2de7699","analyzedAt":"2026-08-16T09:01:53.433Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}