{"record":{"id":"1855ec20a36c0921","repo":"halo-dev/halo","slug":"json-errors-0-1855ec","errorCode":null,"errorMessage":"json.errors[0]","messagePattern":"json\\.errors\\[0\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"application/src/main/resources/templates/gateway_fragments/signup.html","lineNumber":177,"sourceCode":"        const email = document.getElementById(\"email\").value;\n\n        if (!email) {\n          throw new Error(/*[[#{form.emailCode.send.emptyValidation}]]*/ \"\");\n        }\n\n        const response = await fetch(\"/signup/send-email-code\", {\n          method: \"POST\",\n          body: JSON.stringify({ email: email }),\n          headers: {\n            \"Content-Type\": \"application/json\",\n            [headerName]: token,\n          },\n        });\n\n        if (!response.ok) {\n          const json = await response.json();\n          if (json.errors && json.errors.length) {\n            throw new Error(json.errors[0]);\n          }\n        }\n\n        return response;\n      }\n\n      const emailCodeSendButton = document.getElementById(\"emailCodeSendButton\");\n      sendVerificationCode(emailCodeSendButton, sendRequest);\n    });\n  </script>\n</form>\n","sourceCodeStart":159,"sourceCodeEnd":189,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/resources/templates/gateway_fragments/signup.html#L159-L189","documentation":"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.","triggerScenarios":"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.","commonSituations":"CSRF token expired while the signup page stayed open; email already registered; sending too frequently (throttle); invalid email input.","solutions":["Refresh the signup page to get a fresh CSRF token, then retry.","Use a valid, unregistered email address.","Inspect the response body in DevTools to read the exact errors[0] reason.","Wait for the rate-limit window to elapse between sends."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate email and refresh CSRF token before sending in signup:\nif (!email || !/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(email)) {\n    showError(\"Enter a valid email.\"); return;\n}\n// If the signup page was open a long time, reload to refresh the CSRF token.","typeGuard":"function hasErrorsArray(json) {\n  return json != null && Array.isArray(json.errors) && json.errors.length > 0;\n}","tryCatchPattern":"try {\n    await sendRequest();\n} catch (e) {\n    // e.message === server's errors[0]\n    showToast(e.message || \"Failed to send verification code\");\n}","preventionTips":["Refresh the signup page to obtain a fresh CSRF token on long sessions.","Validate the email client-side and ensure it is not already registered.","Throttle the send button to avoid rate-limit responses.","Read errors[0] in DevTools to get the exact rejection reason."],"tags":["frontend","javascript","csrf","email-verification","signup"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}