AlexxIT/go2rtc · warning
empty username or password
Error message
empty username or password
What it means
The handler requires both username and password form fields, but at least one was empty or missing from the multipart form. It rejects the request with HTTP 400 and this static message before any network calls are made.
Solutions
- Include both username and password fields with non-empty values in the multipart form
- Fix field naming on the client to match the handler
- Add client-side required-field validation before submitting
Example fix
// before curl -X POST http://host/api -F 'username=u' // after curl -X POST http://host/api -F 'username=u' -F 'password=p'
Defensive patterns
Strategy: validation
Validate before calling
if r.Form.Get("username") == "" || r.Form.Get("password") == "" {
// return 400 with 'empty username or password' before any network call
} Prevention
- Always send both username and password fields
- Use required attributes on form inputs
- Keep field names consistent between client and server
- Trim whitespace-only values before submission
When it happens
Trigger: POST to the roborock endpoint where r.Form.Get("username") or r.Form.Get("password") returns "" - fields absent, misspelled, or sent with empty values.
Common situations: Form field name mismatch (user vs username); frontend submitted with blank inputs; client only sent one of the two fields.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- either email/password or refresh token is required
- milesone: authentication failed:
- failed to decode hex
- data too short: bytes
- Code must be in the range [0, 125]
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/9e71892875d9ab98.
Report an issue: GitHub.
Appendix: source
Thrown at internal/roborock/roborock.go:43
func apiHandle(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
if Auth.UserData == nil {
http.Error(w, "no auth", http.StatusNotFound)
return
}
case "POST":
if err := r.ParseMultipartForm(1024); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
username := r.Form.Get("username")
password := r.Form.Get("password")
if username == "" || password == "" {
http.Error(w, "empty username or password", http.StatusBadRequest)
return
}
base, err := roborock.GetBaseURL(username)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
ui, err := roborock.Login(base, username, password)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
Auth.BaseURL = base
Auth.UserData = ui
View on GitHub (pinned to c245815e75)