googleapis/mcp-toolbox · error

invalid value for delay: %w

Error message

invalid value for delay: %w

What it means

During Initialize, the alloydb-wait-for-operation tool parses its optional 'delay' field with time.ParseDuration to set the polling interval (default 3s). If the configured string is not a valid Go duration (e.g. '3' or 'three-seconds'), ParseDuration fails and this wrapped error is returned at config load time. The delay must be a Go duration string like '500ms', '2s', or '1m'.

Source

Thrown at internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go:131

func (cfg Config) ToolConfigType() string {
	return resourceType
}

// Initialize initializes the tool from the configuration.
func (cfg Config) Initialize(context.Context) (tools.Tool, error) {

	if cfg.Description == "" {
		cfg.Description = "This will poll on operations API until the operation is done. For checking operation status we need projectId, locationID and operationId. Once instance is created give follow up steps on how to use the variables to bring data plane MCP server up in local and remote setup."
	}

	var delay time.Duration
	if cfg.Delay == "" {
		delay = 3 * time.Second
	} else {
		var err error
		delay, err = time.ParseDuration(cfg.Delay)
		if err != nil {
			return nil, fmt.Errorf("invalid value for delay: %w", err)
		}
	}

	var maxDelay time.Duration
	if cfg.MaxDelay == "" {
		maxDelay = 4 * time.Minute
	} else {
		var err error
		maxDelay, err = time.ParseDuration(cfg.MaxDelay)
		if err != nil {
			return nil, fmt.Errorf("invalid value for maxDelay: %w", err)
		}
	}

	multiplier := cfg.Multiplier
	if multiplier == 0 {
		multiplier = 2.0
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Use a valid Go duration string, e.g. delay: '5s'
  2. Always include a unit suffix (ms, s, m, h) on the numeric value
  3. Remove the delay field entirely to fall back to the 3s default

Example fix

// before
delay: 3
// after
delay: 3s
Defensive patterns

Strategy: validation

Validate before calling

if _, err := time.ParseDuration(cfg.Delay); err != nil {
    return fmt.Errorf("invalid delay %q: use Go duration like 500ms or 3s", cfg.Delay)
}

Type guard

func isValidDuration(s string) bool {
    _, err := time.ParseDuration(s)
    return s == "" || err == nil
}

Try / catch

tool, err := alloydbwaitforoperation.Initialize(cfg)
if err != nil && strings.Contains(err.Error(), "invalid value for delay") {
    return fmt.Errorf("check 'delay' in tools.yaml: %w", err)
}

Prevention

When it happens

Trigger: Configuring delay: '3' (missing unit), delay: 'seconds', delay: '5sec', or any string not accepted by time.ParseDuration in the tool's yaml config.

Common situations: Users assuming plain numbers mean seconds; typos like '30sec' or '1min30s' (space-free compound with unsupported units); copy-pasted values from non-Go tools.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/70cada3fa97829c5. Report an issue: GitHub.