{"record":{"id":"c1dabaca626d10b3","repo":"amir20/dozzle","slug":"container-id-is-required-c1daba","errorCode":null,"errorMessage":"container_id is required","messagePattern":"container_id is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/tools_stream.go","lineNumber":25,"sourceCode":"\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/amir20/dozzle/internal/container\"\n\tpb \"github.com/amir20/dozzle/proto/cloud\"\n\t\"github.com/rs/zerolog/log\"\n)\n\n// streamSender is a function that sends a ToolResponse to the cloud.\ntype streamSender func(resp *pb.ToolResponse) error\n\nfunc parseStreamArgs(argsJSON string) (*fetchLogsArgs, *regexp.Regexp, error) {\n\tvar args fetchLogsArgs\n\tif err := json.Unmarshal([]byte(argsJSON), &args); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse arguments: %w\", err)\n\t}\n\tif args.ContainerID == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"container_id is required\")\n\t}\n\n\tvar re *regexp.Regexp\n\tif args.Regex != \"\" {\n\t\tvar err error\n\t\tre, err = regexp.Compile(args.Regex)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"invalid regex pattern: %w\", err)\n\t\t}\n\t}\n\treturn &args, re, nil\n}\n\nfunc matchesFilters(event *container.LogEvent, args *fetchLogsArgs, re *regexp.Regexp) (string, bool) {\n\tif args.Level != \"\" && !strings.EqualFold(event.Level, args.Level) {\n\t\treturn \"\", false\n\t}\n","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/cloud/tools_stream.go#L7-L43","documentation":"parseStreamArgs requires container_id; after successful JSON unmarshal, an empty container_id string fails this check. The stream_logs tool cannot follow logs without knowing which container to stream from.","triggerScenarios":"executeStreamLogs calls parseStreamArgs with a JSON body that unmarshals fine but leaves args.ContainerID == \"\" (field absent, empty string, or null).","commonSituations":"LLM tool call omitting container_id because it only knew the container name; client sending {\"container_id\": \"\"}; host-only filtering attempted against a per-container stream endpoint.","solutions":["Include a non-empty container_id in the stream_logs arguments","Resolve a container name to an id first via the container listing tool, then pass the id","If unsure which container, list containers first and pick the exact id"],"exampleFix":"// before\nparseStreamArgs(`{\"level\": \"error\"}`)\n// after\nparseStreamArgs(`{\"container_id\": \"a1b2c3\", \"level\": \"error\"}`)","handlingStrategy":"validation","validationCode":"var probe struct{ ContainerID string `json:\"container_id\"` }\nif err := json.Unmarshal([]byte(argsJSON), &probe); err != nil || probe.ContainerID == \"\" {\n  // reject early: container_id missing\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"container_id is required\") {\n  // fetch container id from listing tool, then retry\n}","preventionTips":["Always include container_id in stream_logs arguments","Resolve container names to ids before invoking the stream tool","Validate required fields in tool schemas client-side"],"tags":["cloud-tools","validation","missing-argument"],"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"}