juspay/hyperswitch · error · Error
No token received from login
Error message
No token received from login
What it means
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).
Source
Thrown at cypress-tests/cypress/support/commands.js:6871
method: "POST",
url: url,
headers: {
"Content-Type": "application/json",
},
body: signinBody,
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
cy.wrap(response).then(() => {
if (response.status === 200) {
if (response.body.token_type === "totp") {
expect(response.body, "totp_token").to.have.property("token").and.to
.not.be.empty;
const totpToken = response.body.token;
if (!totpToken) {
throw new Error("No token received from login");
}
globalState.set("totpToken", totpToken);
}
} else {
throw new Error(
`User login call failed to get totp token with status: "${response.status}" and message: "${response.body.error.message}"`
);
}
});
});
});
Cypress.Commands.add("terminate2Fa", (globalState) => {
// Define the necessary variables and constant
const baseUrl = globalState.get("baseUrl");
const queryParams = `skip_two_factor_auth=true`;
const apiKey = globalState.get("totpToken");
const url = `${baseUrl}/user/2fa/terminate?${queryParams}`;
View on GitHub (pinned to 9b8b89dc37)
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
Example fix
// before
const totpToken = response.body.token;
if (!totpToken) throw new Error('No token received from login');
// after
const totpToken = response.body.token;
if (!totpToken)
throw new Error(
`No token received from login: ${JSON.stringify(response.body)}`
); Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the signin contract before relying on the token
const body = response.body;
if (body.token_type === 'totp') {
expect(typeof body.token).to.equal('string');
expect(body.token.length).to.be.greaterThan(0);
} Type guard
const hasNonEmptyToken = (b) => b != null && typeof b.token === 'string' && b.token.length > 0;
Try / catch
try {
await cy.userLogin(globalState);
} catch (e) {
if (/No token received from login/.test(e.message)) {
// inspect full signin response; likely env/server issue, not test logic
throw new Error(`signin returned empty token — check server logs`);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Server bug returning 200 with an empty token; response shape change (token moved/nested); mocking/proxy stripping the token field in local environments.
Related errors
- User login call failed to get totp token with status: "${res
- No user info token available
- User login call failed to fetch user info with status: "${re
- Unsupported connector: ${connectorId}
- Unsupported payment method type: ${payment_method_type}
AI-assisted analysis of juspay/hyperswitch@9b8b89dc37 (2026-08-16).
Data as JSON: /api/errors/72e6f578e5c76918.
Report an issue: GitHub.