vitessio/vitess · error

failed to Execute() template: %v

Error message

failed to Execute() template: %v

What it means

Result.String() renders the throttler result via a statically-defined text/template (resultStringTemplate). Template execution against a struct field set at init time essentially cannot fail at runtime, so any error is treated as an unrecoverable BUG and panics. It means the template and the Result struct are out of sync.

Source

Thrown at go/vt/throttler/result.go:86

	CurrentRate      int64
	GoodOrBad        goodOrBadRate
	MemorySkipReason string
	HighestGood      int64
	LowestBad        int64

	LagRecordNow                 replicationLagRecord
	LagRecordBefore              replicationLagRecord
	PrimaryRate                  int64
	GuessedReplicationRate       int64
	GuessedReplicationBacklogOld int
	GuessedReplicationBacklogNew int
}

func (r Result) String() string {
	var b strings.Builder
	if err := resultStringTemplate.Execute(&b, r); err != nil {
		panic(fmt.Sprintf("failed to Execute() template: %v", err))
	}
	return b.String()
}

func (r Result) Alias() string {
	return topoproto.TabletAliasString(r.LagRecordNow.Tablet.Alias)
}

func (r Result) TimeSinceLastRateChange() string {
	if r.lastRateChange.IsZero() {
		return "n/a"
	}
	return fmt.Sprintf("%.1fs", r.Now.Sub(r.lastRateChange).Seconds())
}

func (r Result) LagBefore() string {
	if r.LagRecordBefore.isZero() {
		return "n/a"

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Update resultStringTemplate so all referenced fields match the current Result struct definition
  2. Run the throttler unit tests to re-validate template rendering after any Result struct change
  3. If seen in a fork, diff your template against upstream go/vt/throttler/result.go

Example fix

// before
template.Must(template.New("result").Parse("{{.LagRecordNow.Noo}}"))
// after
template.Must(template.New("result").Parse("{{.MaxReplicationLag}}"))
Defensive patterns

Strategy: try-catch

Validate before calling

// recover at call boundary in case template state was tampered with
func safeString(r Result) (s string) {
    defer func() { s = recover().(string) }()
    return r.String()
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        log.Errorf("Result.String panic: %v", r)
    }
}()

Prevention

When it happens

Trigger: Calling String() on a throttler Result when resultStringTemplate cannot execute — practically only if the template text was modified to reference a field that no longer exists on Result, or template parsing/execution state was corrupted (e.g. custom build, test stub overriding the template).

Common situations: Merging code changes that renamed a Result field without updating resultStringTemplate; custom forks or tests that replace the package-level template with a malformed one.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/b80e85ffc2bfe5a3. Report an issue: GitHub.