halo-dev/halo · warning · Error

i18nResources.sendVerificationCodeFailed

Error message

i18nResources.sendVerificationCodeFailed

What it means

Client-side JS fallback in the complete-profile flow: when /complete-profile/send-email-code returns a non-ok response whose body has neither a usable errors array nor a detail field, sendRequest() throws new Error(i18nResources.sendVerificationCodeFailed) — a generic localized message ('Sending Failed, Please Try Again Later' / '发送失败,请稍后再试'). It is the catch-all branch so the user always sees some message.

Source

Thrown at application/src/main/resources/templates/gateway_fragments/complete_profile.html:92

        const email = document.getElementById("email").value;
        const response = await fetch("/complete-profile/send-email-code", {
          method: "POST",
          body: JSON.stringify({ email: email }),
          headers: {
            "Content-Type": "application/json",
            [headerName]: token,
          },
        });

        if (!response.ok) {
          const json = await response.json();
          if (json.errors && json.errors.length) {
            throw new Error(json.errors[0]);
          }
          if (json.detail) {
            throw new Error(json.detail);
          }
          throw new Error(i18nResources.sendVerificationCodeFailed);
        }

        return response;
      }

      const emailCodeSendButton = document.getElementById("emailCodeSendButton");
      sendVerificationCode(emailCodeSendButton, sendRequest);
    });
  </script>
</form>

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Open DevTools -> Network and inspect the raw response status and body to see why it is not ok and why no errors/detail were found.
  2. Retry the request; transient gateway/network errors usually clear.
  3. Refresh the page to reset CSRF and session state.
  4. If persistent, check that the backend /complete-profile/send-email-code route is up and returning its documented error shape.
Defensive patterns

Strategy: fallback

Validate before calling

// Guard against non-JSON / unexpected bodies before throwing:
let json;
try { json = await response.json(); } catch { json = null; }
if (json?.errors?.length) throw new Error(json.errors[0]);
if (json?.detail) throw new Error(json.detail);
// Provide a richer fallback using response.status:
throw new Error(`${i18nResources.sendVerificationCodeFailed} (HTTP ${response.status})`);

Type guard

function hasUsableErrorBody(json) {
  return json != null &&
    ((Array.isArray(json.errors) && json.errors.length > 0) ||
     (typeof json.detail === "string" && json.detail.length > 0));
}

Try / catch

try {
    await sendRequest();
} catch (e) {
    // generic localized failure
    showToast(i18nResources.sendVerificationCodeFailed);
    console.error("send-email-code failed:", e);
}

Prevention

When it happens

Trigger: The response is not ok but the body shape is unexpected: empty body, non-JSON body, network/proxy error page (HTML), or a JSON object lacking both errors and detail.

Common situations: Reverse proxy returning an HTML error page (502/504) with JSON parse yielding an object without errors/detail; response body empty; network glitch; the endpoint changed its error contract.

Related errors


AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14). Data as JSON: /api/errors/6750436c45909e13. Report an issue: GitHub.