SigNoz/signoz · error

ErrCodePublicDashboardInvalidInput

ErrCodePublicDashboardInvalidInput

Error message

unable to parse defaultTimeRange %s

What it means

PostablePublicDashboard.UnmarshalJSON parses the incoming public-dashboard payload and requires the DefaultTimeRange field to be a valid Go duration string (time.ParseDuration, e.g. "30m", "24h"). If parsing fails, the request is rejected with ErrCodePublicDashboardInvalidInput including the offending value.

Source

Thrown at pkg/types/dashboardtypes/public_dashboard.go:250

	timeRange, err := time.ParseDuration(typ.DefaultTimeRange)
	if err != nil {
		return 0, 0, errors.WrapInternalf(err, errors.CodeInternal, "stored defaultTimeRange %q is not a valid duration", typ.DefaultTimeRange)
	}
	now := time.Now()
	return uint64(now.Add(-timeRange).UnixMilli()), uint64(now.UnixMilli()), nil
}

func (typ *PostablePublicDashboard) UnmarshalJSON(data []byte) error {
	type alias PostablePublicDashboard
	var temp alias

	if err := json.Unmarshal(data, &temp); err != nil {
		return err
	}

	_, err := time.ParseDuration(temp.DefaultTimeRange)
	if err != nil {
		return errors.Wrapf(err, errors.TypeInvalidInput, ErrCodePublicDashboardInvalidInput, "unable to parse defaultTimeRange %s", temp.DefaultTimeRange)
	}

	*typ = PostablePublicDashboard(temp)
	return nil
}

func (typ *UpdatablePublicDashboard) UnmarshalJSON(data []byte) error {
	type alias UpdatablePublicDashboard
	var temp alias

	if err := json.Unmarshal(data, &temp); err != nil {
		return err
	}

	_, err := time.ParseDuration(temp.DefaultTimeRange)
	if err != nil {
		return errors.Wrapf(err, errors.TypeInvalidInput, ErrCodePublicDashboardInvalidInput, "unable to parse defaultTimeRange %s", temp.DefaultTimeRange)
	}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Use exact Go duration syntax: ns, us (or µs), ms, s, m, h, e.g. "30m", "1h", "45s"
  2. Compound values are allowed like "1h30m"; decimals like "1.5h" also work
  3. Verify no stray whitespace or quotes around the value in the JSON body

Example fix

// before
{"defaultTimeRange": "30 minutes"}

// after
{"defaultTimeRange": "30m"}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := time.ParseDuration(payload.DefaultTimeRange); err != nil {
    payload.DefaultTimeRange = "1h" // or reject
}

Type guard

func isValidGoDuration(s string) bool { _, err := time.ParseDuration(s); return err == nil }

Prevention

When it happens

Trigger: POST/PUT of a public dashboard (create/update endpoint) whose JSON body has defaultTimeRange like "30 minutes", "1d", "30sec", "", or an ISO 8601 duration ("PT30M") — none are accepted by time.ParseDuration (which wants "30m", "1h30m", "0.5h").

Common situations: Frontends or scripts copying duration formats from other tools (ISO 8601, human text); omitting the field when the type defaults to empty string; unit suffix typos like "30M" (uppercase M is minutes? no—ParseDuration is case-sensitive: 'M' is invalid, only m/h/s/ms/us/ns).

Understand the failure class

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/d5e090be0ffdb516. Report an issue: GitHub.