Tencent/WeKnora · error

unsupported timeout mode %q

Error message

unsupported timeout mode %q

What it means

e2bTimeoutSeconds converts a provider-neutral timeout policy into E2B seconds. The E2B backend only supports explicit finite timeouts; any other TimeoutMode (e.g. NeverTimeout-style modes besides RemoteTimeoutExplicit) falls into the default branch and is rejected because the SDK's SetTimeout API takes a concrete duration.

Source

Thrown at internal/sandbox/e2b_remote_client.go:1105

		if value%time.Second != 0 {
			seconds++
		}
		return int(seconds), nil
	}

	switch policy.Mode {
	case "", RemoteTimeoutServerDefault:
		if fallback <= 0 {
			return 0, nil
		}
		return toSeconds(fallback)
	case RemoteTimeoutExplicit:
		if policy.Value < 0 {
			return 0, errors.New("E2B backend does not support NeverTimeout")
		}
		return toSeconds(policy.Value)
	default:
		return 0, fmt.Errorf("unsupported timeout mode %q", policy.Mode)
	}
}

// toE2BVolumeMounts converts the provider-neutral RemoteVolumeMount slice to
// E2B SDK VolumeMount values. Nil and empty inputs both produce nil.
func toE2BVolumeMounts(src []RemoteVolumeMount) []e2b.VolumeMount {
	if len(src) == 0 {
		return nil
	}
	result := make([]e2b.VolumeMount, len(src))
	for i, mount := range src {
		result[i] = e2b.VolumeMount{
			Name: mount.Name,
			Path: mount.Path,
		}
	}
	return result
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set the timeout policy mode to RemoteTimeoutExplicit with a non-negative Value before constructing/using the E2B client.
  2. If you need an effectively infinite timeout, choose the largest acceptable explicit duration instead of a NeverTimeout-style mode.
  3. If the policy comes from config parsing, normalize unknown/empty modes to RemoteTimeoutExplicit with DefaultE2BSandboxTTL seconds.
  4. Add an early config-validation step that maps or rejects non-explicit timeout modes for E2B-specific deployments.

Example fix

// before
policy := RemoteTimeoutPolicy{Mode: RemoteTimeoutNever}
// after
policy := RemoteTimeoutPolicy{Mode: RemoteTimeoutExplicit, Value: 30 * time.Minute}
Defensive patterns

Strategy: validation

Validate before calling

if policy.Mode != RemoteTimeoutExplicit {
    return fmt.Errorf("E2B requires RemoteTimeoutExplicit, got %q", policy.Mode)
}
if policy.Value < 0 {
    return errors.New("E2B requires non-negative timeout")
}

Type guard

func isExplicitTimeout(p RemoteTimeoutPolicy) bool {
    return p.Mode == RemoteTimeoutExplicit && p.Value >= 0
}

Prevention

When it happens

Trigger: Calling Create, Connect, Get, Delete, or CreateSnapshot on the E2B remote client when the configured sandbox timeout policy has a Mode other than RemoteTimeoutExplicit; the message interpolates the offending mode string (e.g. %q shows "never").

Common situations: Configuring a shared timeout policy intended for local/Docker sandboxes (which support idle/never-timeout semantics) and reusing it for E2B; copying a config where the mode field was defaulted or set from YAML/JSON to a value like 'never' or '' without noticing E2B's restriction; setting policy.Value but forgetting to set Mode to RemoteTimeoutExplicit.

Understand the failure class

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/496fc8988b3c8484. Report an issue: GitHub.