{"record":{"id":"b518d5f506651cb9","repo":"amir20/dozzle","slug":"stdout-or-stderr-is-required-b518d5","errorCode":null,"errorMessage":"stdout or stderr is required","messagePattern":"stdout or stderr is required","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"internal/web/logs.go","lineNumber":108,"sourceCode":"\t}\n\treturn ids\n}\n\nfunc (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request) {\n\tplainText := strings.Contains(r.Header.Get(\"Accept\"), \"text/plain\")\n\tif plainText {\n\t\tw.Header().Set(\"Content-Type\", \"text/plain; charset=UTF-8\")\n\t} else {\n\t\tw.Header().Set(\"Content-Type\", \"application/x-jsonl; charset=UTF-8\")\n\t}\n\n\tfrom, _ := time.Parse(time.RFC3339Nano, r.URL.Query().Get(\"from\"))\n\tto, _ := time.Parse(time.RFC3339Nano, r.URL.Query().Get(\"to\"))\n\tid := chi.URLParam(r, \"id\")\n\n\tstdTypes := parseStdTypes(r)\n\tif stdTypes == 0 {\n\t\thttp.Error(w, \"stdout or stderr is required\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tcontainerService, err := h.hostService.FindContainer(hostKey(r), id, h.resolveLabels(r))\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusNotFound)\n\t\treturn\n\t}\n\n\tdelta := max(to.Sub(from), time.Second*3)\n\n\tvar regex *regexp.Regexp\n\tif r.URL.Query().Has(\"filter\") {\n\t\tregex, err = support_web.ParseRegex(r.URL.Query().Get(\"filter\"))\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\treturn\n\t\t}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/web/logs.go#L90-L126","documentation":"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.","triggerScenarios":"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).","commonSituations":"Hand-built API calls omitting the parameter; scripts copying stream values from other log tools; frontend regressions dropping the query param.","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."],"exampleFix":"// before\nconst url = `/api/hosts/${host}/containers/${id}/logs?from=${from}&to=${to}`\n// after\nconst url = `/api/hosts/${host}/containers/${id}/logs?from=${from}&to=${to}&stdtypes=stdout%2Cstderr`","handlingStrategy":"validation","validationCode":"function assertStdTypes(std) {\n  const valid = ['stdout', 'stderr'];\n  const parts = (std || '').split(',').filter(Boolean);\n  if (parts.length === 0 || parts.some(p => !valid.includes(p))) throw new Error('stdout or stderr is required');\n}\nassertStdTypes(stdtypes);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["http","validation","query-params"],"backgroundTag":"missing-required-argument","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}