amir20/dozzle · error

failed to parse arguments

Error message

failed to parse arguments: %w

What it means

executeFetchContainerLogs unmarshals its JSON arguments into fetchLogsArgs (containerId, host, level, query, regex, start/end times, etc.). Invalid JSON or wrong-typed fields cause json.Unmarshal to fail and the error is wrapped with this message before any container lookup happens.

Solutions

  1. Escape any user-supplied query/regex strings before embedding them in the JSON arguments.
  2. Validate that all fields are strings per the fetchLogsArgs json tags and the tool schema.
  3. Inspect the wrapped json error's offset/field to find the exact malformed token.

Example fix

// before (unescaped backslash/quote in regex)
{"containerId":"a1","regex":"error \"fatal\""}
// after
{"containerId":"a1","regex":"error \"fatal\""} with proper JSON escaping: "error \"fatal\"" -> use json.Marshal to build args
Defensive patterns

Strategy: validation

Validate before calling

const args = { containerId: String(id), host, level, query, regex, start, end };
const argsJSON = JSON.stringify(args); // escapes any user-supplied regex/query safely
JSON.parse(argsJSON); // early check

Try / catch

try {
  return await callTool("fetch_container_logs", argsJSON);
} catch (e) {
  if (String(e).includes("failed to parse arguments")) {
    // most likely unescaped user text in query/regex; rebuild with JSON.stringify
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling fetch_container_logs with malformed arguments: unescaped quotes in a regex/query string, non-string values for containerId/host/start/end, or a non-object payload.

Common situations: Agents embedding user-provided regex or query text into JSON without escaping; RFC3339 timestamps accidentally passed as numbers; double-encoded argument blobs from intermediate proxies.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/d80afa9af166c0dd. Report an issue: GitHub.

Appendix: source

Thrown at internal/cloud/tools_logs.go:28

	"github.com/amir20/dozzle/internal/container"
	pb "github.com/amir20/dozzle/proto/cloud"
)

type fetchLogsArgs struct {
	ContainerID string `json:"container_id"`
	Host        string `json:"host_id"`
	Start       string `json:"start"`
	End         string `json:"end"`
	Level       string `json:"level"`
	Query       string `json:"query"`
	Regex       string `json:"regex"`
	Inverse     bool   `json:"inverse"`
}

func executeFetchContainerLogs(ctx context.Context, argsJSON string, deps ToolDeps) (*pb.CallToolResponse, error) {
	var args fetchLogsArgs
	if err := json.Unmarshal([]byte(argsJSON), &args); err != nil {
		return nil, fmt.Errorf("failed to parse arguments: %w", err)
	}
	hostID, containerID, note, err := resolveContainerRefRead(args.ContainerID, args.Host, deps)
	if err != nil {
		return nil, err
	}

	cs, err := deps.HostService.FindContainer(hostID, containerID, deps.Labels)
	if err != nil {
		return nil, fmt.Errorf("container not found: %w", err)
	}

	start := time.Now().Add(-1 * time.Hour)
	end := time.Now()
	if args.Start != "" {
		t, err := time.Parse(time.RFC3339, args.Start)
		if err != nil {
			return nil, fmt.Errorf("invalid start time format (expected RFC3339): %w", err)
		}

View on GitHub (pinned to d9463cbe21)