{"record":{"id":"3ec6ab068259f368","repo":"amir20/dozzle","slug":"failed-to-parse-arguments-w-3ec6ab","errorCode":null,"errorMessage":"failed to parse arguments: %w","messagePattern":"failed to parse arguments: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/tools_helpers.go","lineNumber":18,"sourceCode":"package cloud\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\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// parseArgs unmarshals argsJSON into a fresh value of T.\nfunc parseArgs[T any](argsJSON string) (T, error) {\n\tvar args T\n\tif err := json.Unmarshal([]byte(argsJSON), &args); err != nil {\n\t\treturn args, fmt.Errorf(\"failed to parse arguments: %w\", err)\n\t}\n\treturn args, nil\n}\n\n// buildHostNameMap creates a mapping from host ID to host name.\nfunc buildHostNameMap(hostService ToolHostService) map[string]string {\n\thosts := hostService.Hosts()\n\tm := make(map[string]string, len(hosts))\n\tfor _, h := range hosts {\n\t\tm[h.ID] = h.Name\n\t}\n\treturn m\n}\n\n// resolveHostName returns the host name for a given host ID, falling back to the ID itself.\nfunc resolveHostName(hostID string, hostNames map[string]string) string {\n\tif name, ok := hostNames[hostID]; ok {\n\t\treturn name","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/cloud/tools_helpers.go#L1-L36","documentation":"parseArgs is a generic helper that unmarshals a tool-call argsJSON string into a struct of type T. Any invalid JSON (syntax error or type mismatch against T) produces this wrapped error, which callers return as-is to the tool dispatcher.","triggerScenarios":"Any cloud tool using parseArgs receiving argsJSON that is not valid JSON for its target struct: empty string where args are required, trailing commas, wrong field types, or double-encoded JSON.","commonSituations":"Tool implementations forgetting that parseArgs (unlike executeFindContainers) does not tolerate empty args; agents emitting JSON strings instead of objects; struct field type changes making previously valid payloads invalid.","solutions":["Check the wrapped json error (errors.As for *json.UnmarshalTypeError or *json.SyntaxError) to pinpoint the bad field or offset.","Ensure required tools receive a non-empty JSON object for argsJSON.","Keep the Go args struct field types and json tags in sync with the schema published in AvailableTools()."],"exampleFix":"// before\nargs, err := parseArgs[fetchLogsArgs](\"\") // empty string -> parse error\n// after\nif argsJSON == \"\" { return nil, errors.New(\"missing required arguments\") }\nargs, err := parseArgs[fetchLogsArgs](argsJSON)","handlingStrategy":"validation","validationCode":"function safeArgs(obj) {\n  if (obj === undefined || obj === null) throw new Error(\"parseArgs requires a non-empty args object\");\n  return JSON.stringify(obj); // guarantees syntactically valid JSON\n}","typeGuard":null,"tryCatchPattern":"args, err := parseArgs[fetchLogsArgs](argsJSON)\nif err != nil {\n    var typeErr *json.UnmarshalTypeError\n    if errors.As(err, &typeErr) {\n        return nil, fmt.Errorf(\"field %s has wrong type\", typeErr.Field)\n    }\n    return nil, err\n}","preventionTips":["Never pass an empty string to parseArgs for tools with required arguments.","Keep Go args struct json tags aligned with the published tool schema.","Unit-test each tool's parseArgs path with valid and invalid payloads."],"tags":["json","cloud-tools","generics"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}