antiwork/gumroad · error · ResponseError
No recovery codes were generated. Please try again.
Error message
No recovery codes were generated. Please try again.
What it means
Thrown when recovery-code regeneration succeeded at the HTTP level (response.ok, success:true) but the payload's recovery_codes array is missing or empty. This is a contract violation between controller and client: the endpoint reported success without delivering codes, and the client refuses to overwrite the UI with an empty list. It is intentionally a different message from the generic failure so this drift is visible in support reports.
Source
Thrown at app/javascript/pages/Settings/Password/Show.tsx:111
const handleRegenerateRecoveryCodes = asyncVoid(async () => {
setRegenerating(true);
try {
const response = await request({
url: Routes.regenerate_recovery_codes_settings_totp_path(),
method: "POST",
accept: "json",
});
const result = typia.assert<{ success: boolean; recovery_codes?: string[]; error_message?: string }>(
await response.json(),
);
if (!response.ok || !result.success) {
throw new ResponseError(result.error_message ?? "Sorry, something went wrong. Please try again.");
}
if (!result.recovery_codes?.length) {
throw new ResponseError("No recovery codes were generated. Please try again.");
}
setRegeneratedCodes(result.recovery_codes);
} catch (e) {
assertResponseError(e);
showAlert(e.message, "error");
} finally {
setRegenerating(false);
}
});
return (
<SettingsLayout currentPage="password" pages={props.settings_pages}>
<form onSubmit={handleSubmit}>
<FormSection header={<h2>Change password</h2>}>
{requireOldPassword ? (
<Fieldset>
<FieldsetTitle>
<Label htmlFor={`${uid}-old-password`}>Old password</Label>View on GitHub (pinned to afeacbd394)
Solutions
- Retry the regeneration — transient generation failures often resolve on a second attempt.
- If it reproduces, inspect the response body: success:true plus empty codes is a server contract bug, not user error.
- Maintainers: fix the controller to always return a non-empty recovery_codes on success, or success:false with error_message.
- Add an endpoint test asserting recovery_codes is present and non-empty for every success response.
Example fix
# Rails controller, before
render json: { success: true }
# after
codes = generate_recovery_codes
if codes.empty?
render json: { success: false, error_message: "Could not generate codes." }, status: :internal_server_error
else
render json: { success: true, recovery_codes: codes }
end Defensive patterns
Strategy: validation
Validate before calling
const hasRecoveryCodes = (body: { success: boolean; recovery_codes?: string[] }): boolean =>
body.success && Array.isArray(body.recovery_codes) && body.recovery_codes.length > 0; Type guard
type RecoveryCodesResponse =
| { success: true; recovery_codes: [string, ...string[]] }
| { success: false; error_message: string };
const isUsableRecoveryCodesResponse = (b: { success: boolean; recovery_codes?: string[] }): b is RecoveryCodesResponse =>
b.success === false || (Array.isArray(b.recovery_codes) && b.recovery_codes.length > 0); Try / catch
try {
const result = typia.assert<{ success: boolean; recovery_codes?: string[]; error_message?: string }>(await response.json());
if (!response.ok || !result.success) throw new ResponseError(result.error_message ?? GENERIC);
if (!result.recovery_codes?.length) throw new ResponseError("No recovery codes were generated. Please try again.");
setRegeneratedCodes(result.recovery_codes);
} catch (e) {
assertResponseError(e);
showAlert(e.message, "error");
} Prevention
- Never trust success flags alone — validate the payload you actually need before acting on it.
- Contract-test success responses (non-empty arrays, required fields) at the endpoint level.
- Use typia tuple/non-empty-array types so shape drift fails at the assert instead of after it.
When it happens
Trigger: POST regenerate_recovery_codes_settings_totp_path returns { success: true } with recovery_codes: [] or the key omitted entirely — controller bug, partial serialization, or an intermittent generation path that yields no codes.
Common situations: Rails serializer changes dropping the field, caching layers stripping payloads, tests stubbing the endpoint with success-only fixtures; users click 'Regenerate codes' and get this error with no codes shown.
Related errors
- ${responseData.error}
- responseData.error_message
- Sorry, something went wrong. Please try again.
- Sorry, something went wrong. Please try again.
- Something went wrong.
AI-assisted analysis of antiwork/gumroad@afeacbd394 (2026-08-21).
Data as JSON: /api/errors/4b92562df18eaeb8.
Report an issue: GitHub.