halo-dev/halo · warning · Error

json.errors[0]

Error message

json.errors[0]

What it means

Client-side JS in the signup flow: sendRequest() POSTs to /signup/send-email-code with the CSRF header. If the response is not ok and the parsed body has a non-empty errors array, it throws new Error(json.errors[0]) — the message is the first server-provided error string. Note signup.html only checks json.errors (no detail/fallback branches), so if the body has no errors array the function returns the non-ok response without throwing and the shared sendVerificationCode() handles the failure.

Source

Thrown at application/src/main/resources/templates/gateway_fragments/signup.html:177

        const email = document.getElementById("email").value;

        if (!email) {
          throw new Error(/*[[#{form.emailCode.send.emptyValidation}]]*/ "");
        }

        const response = await fetch("/signup/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]);
          }
        }

        return response;
      }

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

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Refresh the signup page to get a fresh CSRF token, then retry.
  2. Use a valid, unregistered email address.
  3. Inspect the response body in DevTools to read the exact errors[0] reason.
  4. Wait for the rate-limit window to elapse between sends.
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate email and refresh CSRF token before sending in signup:
if (!email || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
    showError("Enter a valid email."); return;
}
// If the signup page was open a long time, reload to refresh the CSRF token.

Type guard

function hasErrorsArray(json) {
  return json != null && Array.isArray(json.errors) && json.errors.length > 0;
}

Try / catch

try {
    await sendRequest();
} catch (e) {
    // e.message === server's errors[0]
    showToast(e.message || "Failed to send verification code");
}

Prevention

When it happens

Trigger: The signup email-code endpoint rejects the request and returns a body with an `errors` array — e.g. invalid email, email already registered, rate limiting, or an expired/stale CSRF token on a long-open signup form.

Common situations: CSRF token expired while the signup page stayed open; email already registered; sending too frequently (throttle); invalid email input.

Related errors


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