amir20/dozzle · error

invalid start time format (expected RFC3339)

Error message

invalid start time format (expected RFC3339): %w

What it means

executeFetchContainerLogs parses the optional start argument with time.Parse(time.RFC3339, ...). When the string is present but not a valid RFC3339 timestamp, the underlying parse error is wrapped as 'invalid start time format (expected RFC3339)' and returned as a tool-call failure. This is strict input validation on the log-fetch tool's date range.

Solutions

  1. Pass the start time as RFC3339 with timezone, e.g. 2024-05-01T10:00:00Z
  2. Omit the start argument entirely (it defaults to one hour ago)
  3. Normalize relative expressions ('1h ago') to absolute RFC3339 before calling the tool

Example fix

// before
{"container_id":"abc","start":"1 hour ago"}
// after
{"container_id":"abc","start":"2024-05-01T09:00:00Z"}
Defensive patterns

Strategy: validation

Validate before calling

function isValidRFC3339(s) { if (!s) return true; return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/.test(s) && !isNaN(Date.parse(s)); }
if (args.start && !isValidRFC3339(args.start)) args.start = new Date(Date.now() - 3600e3).toISOString();

Type guard

null

Prevention

When it happens

Trigger: Calling the fetch_container_logs cloud tool with args.start set to a non-RFC3339 value such as '1h ago', '2024-01-01', '1700000000' (unix seconds), or a timestamp missing timezone info like '2024-01-01T10:00:00'.

Common situations: LLM tool callers passing human-readable relative times instead of ISO timestamps; clients generating timestamps without timezone offsets; code constructing dates with date.toString() instead of toISOString().

Related errors


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

Appendix: source

Thrown at internal/cloud/tools_logs.go:45

	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)
		}
		start = t
	}
	if args.End != "" {
		t, err := time.Parse(time.RFC3339, args.End)
		if err != nil {
			return nil, fmt.Errorf("invalid end time format (expected RFC3339): %w", err)
		}
		end = t
	}

	var re *regexp.Regexp
	if args.Regex != "" {
		var err error
		re, err = regexp.Compile(args.Regex)
		if err != nil {
			return nil, fmt.Errorf("invalid regex pattern: %w", err)
		}

View on GitHub (pinned to d9463cbe21)