amir20/dozzle · warning
stdout or stderr is required
Error message
stdout or stderr is required
What it means
fetchLogsBetweenDates parses the stdtypes query parameter into a bitmask; when neither stdout nor stderr is requested the mask is 0 and the handler rejects the request with 400 "stdout or stderr is required" before doing any container lookup.
Solutions
- Pass stdtypes=stdout, stderr, or stdout%2Cstderr in the query string.
- Omit other unrecognized values so the mask does not come out empty.
- Default to requesting both streams when the caller does not care.
Example fix
// before
const url = `/api/hosts/${host}/containers/${id}/logs?from=${from}&to=${to}`
// after
const url = `/api/hosts/${host}/containers/${id}/logs?from=${from}&to=${to}&stdtypes=stdout%2Cstderr` Defensive patterns
Strategy: validation
Validate before calling
function assertStdTypes(std) {
const valid = ['stdout', 'stderr'];
const parts = (std || '').split(',').filter(Boolean);
if (parts.length === 0 || parts.some(p => !valid.includes(p))) throw new Error('stdout or stderr is required');
}
assertStdTypes(stdtypes); Prevention
- Always send stdtypes with values limited to stdout and/or stderr.
- Default missing stdtypes to 'stdout,stderr' in client code.
- Validate query params when constructing API URLs programmatically.
When it happens
Trigger: GET /api/hosts/{host}/containers/{id}/logs with stdtypes missing, empty, or set to an unrecognized value so parseStdTypes returns 0 (e.g. stdtypes=both or stdtypes=1 when only named values are accepted).
Common situations: Hand-built API calls omitting the parameter; scripts copying stream values from other log tools; frontend regressions dropping the query param.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/b518d5f506651cb9.
Report an issue: GitHub.
Appendix: source
Thrown at internal/web/logs.go:108
}
return ids
}
func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request) {
plainText := strings.Contains(r.Header.Get("Accept"), "text/plain")
if plainText {
w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
} else {
w.Header().Set("Content-Type", "application/x-jsonl; charset=UTF-8")
}
from, _ := time.Parse(time.RFC3339Nano, r.URL.Query().Get("from"))
to, _ := time.Parse(time.RFC3339Nano, r.URL.Query().Get("to"))
id := chi.URLParam(r, "id")
stdTypes := parseStdTypes(r)
if stdTypes == 0 {
http.Error(w, "stdout or stderr is required", http.StatusBadRequest)
return
}
containerService, err := h.hostService.FindContainer(hostKey(r), id, h.resolveLabels(r))
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
delta := max(to.Sub(from), time.Second*3)
var regex *regexp.Regexp
if r.URL.Query().Has("filter") {
regex, err = support_web.ParseRegex(r.URL.Query().Get("filter"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}View on GitHub (pinned to d9463cbe21)