Tencent/WeKnora · error

unsupported timeout mode %q

Error message

unsupported timeout mode %q

What it means

cubeTimeout maps a timeout policy's Mode to a concrete Cube SDK timeout value. The switch handles the known modes (including a mode treated as NeverTimeout for negative values); any unrecognized Mode string reaches the default branch and produces this error, aborting Create before the sandbox is provisioned.

Source

Thrown at internal/sandbox/cube_remote_client.go:941

	lower := strings.ToLower(err.Error())
	return strings.Contains(lower, "not found") ||
		strings.Contains(lower, "no such file") ||
		strings.Contains(lower, "sandbox_not_found") ||
		strings.Contains(lower, "http 404")
}

func cubeTimeout(policy RemoteTimeoutPolicy) (*time.Duration, error) {
	switch policy.Mode {
	case "", RemoteTimeoutServerDefault:
		return nil, nil
	case RemoteTimeoutExplicit:
		value := policy.Value
		if value < 0 {
			value = cubesandbox.NeverTimeout
		}
		return &value, nil
	default:
		return nil, fmt.Errorf("unsupported timeout mode %q", policy.Mode)
	}
}

// cubeHandleSandbox extracts the SDK *cubesandbox.Sandbox from an opaque
// RemoteSandboxHandle. Returns an error when the handle is nil, not Cube,
// or has an empty sandbox ID.
func cubeHandleSandbox(op string, handle RemoteSandboxHandle) (*cubesandbox.Sandbox, error) {
	cubeHandle, ok := handle.(*cubeRemoteHandle)
	if !ok || cubeHandle == nil || cubeHandle.sb == nil ||
		strings.TrimSpace(cubeHandle.sb.SandboxID) == "" {
		return nil, cubeInvalidRequest(op, "handle was not issued by Cube", nil)
	}
	return cubeHandle.sb, nil
}

// cubeRemoteSummary converts the SDK's SandboxInfo (from List / GetInfo) into
// the provider-neutral RemoteSandboxSummary DTO.
func cubeRemoteSummary(info cubesandbox.SandboxInfo) *RemoteSandboxSummary {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set policy.Mode using the library's exported timeout mode constants instead of raw strings
  2. Inspect the %q value in the error and correct it to a supported mode name
  3. If the value came from a persisted config, re-serialize it with the current library version to migrate mode names
  4. Check for whitespace/case differences — modes are matched exactly by the switch

Example fix

// before
policy := TimeoutPolicy{Mode: "forever"} // unknown mode
// after
policy := TimeoutPolicy{Mode: TimeoutModeNever} // use exported constant; NeverTimeout applies for negative values
Defensive patterns

Strategy: validation

Validate before calling

switch policy.Mode {
case TimeoutModeFixed, TimeoutModeNever, TimeoutModeDefault:
default:
    return fmt.Errorf("unknown timeout mode %q before calling Create", policy.Mode)
}

Type guard

func isKnownTimeoutMode(m TimeoutMode) bool {
    switch m { case TimeoutModeFixed, TimeoutModeNever, TimeoutModeDefault: return true }
    return false
}

Try / catch

sb, err := client.Create(ctx, spec)
if err != nil {
    if strings.Contains(err.Error(), "unsupported timeout mode") { /* fix policy.Mode to an exported constant */ }
    return err
}

Prevention

When it happens

Trigger: Building a TimeoutPolicy with a Mode value that the mapper does not recognize (typo, renamed enum constant, stale serialized config from an older version) and calling Create, which resolves the policy via cubeTimeout.

Common situations: Hand-writing a policy mode string instead of using the exported constants; a config file persisted by an older library version whose mode names changed; copy-pasting policy YAML from another sandbox backend with different mode vocabulary.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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