fatedier/frp · error

visitor name cannot be empty

Error message

visitor name cannot be empty

What it means

A visitor entry in the store file decoded successfully but its base config Name is empty. Visitors are stored in a map keyed by name, so a nameless visitor entry makes the whole file unloadable; loading aborts at the first such entry.

Source

Thrown at pkg/config/source/store.go:117

			return fmt.Errorf("failed to decode proxy at index %d: %w", i, err)
		}
		name := proxyCfg.GetBaseConfig().Name
		if name == "" {
			return fmt.Errorf("proxy name cannot be empty")
		}
		s.proxies[name] = proxyCfg
	}

	for i, visitorData := range stored.Visitors {
		visitorCfg, err := v1.DecodeVisitorConfigurerJSON(visitorData, v1.DecodeOptions{
			DisallowUnknownFields: false,
		})
		if err != nil {
			return fmt.Errorf("failed to decode visitor at index %d: %w", i, err)
		}
		name := visitorCfg.GetBaseConfig().Name
		if name == "" {
			return fmt.Errorf("visitor name cannot be empty")
		}
		s.visitors[name] = visitorCfg
	}

	return nil
}

func (s *StoreSource) saveToFileUnlocked() error {
	stored := storeData{
		Proxies:  make([]v1.TypedProxyConfig, 0, len(s.proxies)),
		Visitors: make([]v1.TypedVisitorConfig, 0, len(s.visitors)),
	}

	for _, p := range s.proxies {
		stored.Proxies = append(stored.Proxies, v1.TypedProxyConfig{ProxyConfigurer: p})
	}
	for _, v := range s.visitors {
		stored.Visitors = append(stored.Visitors, v1.TypedVisitorConfig{VisitorConfigurer: v})

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Scan the visitors array in the store file for entries missing "name"
  2. Give every visitor a unique non-empty name
  3. Remove incomplete entries if unintended
  4. Retry loading

Example fix

// before
{ "visitors": [ { "type": "stcp", "serverName": "ssh" } ] }

// after
{ "visitors": [ { "type": "stcp", "name": "ssh-v", "serverName": "ssh" } ] }
Defensive patterns

Strategy: validation

Validate before calling

func validateVisitorNames(path string) error {
	data, _ := os.ReadFile(path)
	var raw struct {
		Visitors []struct{ Name string `json:"name"` } `json:"visitors"`
	}
	if json.Unmarshal(data, &raw) != nil {
		return nil
	}
	for i, v := range raw.Visitors {
		if strings.TrimSpace(v.Name) == "" {
			return fmt.Errorf("visitors[%d] has empty name", i)
		}
	}
	return nil
}

Prevention

When it happens

Trigger: A visitors array element in the store file that omits "name" or sets it to "". Typically from hand-editing or a code-generated store where the name field was skipped for one entry.

Common situations: Template/script generating visitor entries without names; migration tools that drop empty-but-present fields and accidentally drop name; copy-paste of an example visitor config that used a placeholder.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/85b141fedcdb44d6. Report an issue: GitHub.