sipeed/picoclaw · error

host cannot be empty

Error message

host cannot be empty

What it means

parseHostTokens rejects a host specification that is empty after strings.TrimSpace. This parser turns a comma-separated host list ("localhost", "*", IPs, names) into bind tokens for building a netbind Plan, so an entirely blank spec cannot produce a bind group.

Source

Thrown at pkg/netbind/netbind.go:426

		return ResolveAdaptiveLoopbackHost()
	case hasIPv6Any:
		return "::1"
	case hasIPv4Any:
		return "127.0.0.1"
	}

	for _, group := range groups {
		if group.kind == groupExact {
			return group.exact.host
		}
	}
	return ResolveAdaptiveLoopbackHost()
}

func parseHostTokens(raw string) ([]hostToken, error) {
	raw = strings.TrimSpace(raw)
	if raw == "" {
		return nil, errors.New("host cannot be empty")
	}

	parts := strings.Split(raw, ",")
	tokens := make([]hostToken, 0, len(parts))
	seen := make(map[string]struct{}, len(parts))
	for _, part := range parts {
		token, err := parseHostToken(part)
		if err != nil {
			return nil, err
		}
		if _, ok := seen[token.key]; ok {
			continue
		}
		seen[token.key] = struct{}{}
		tokens = append(tokens, token)
	}

	if len(tokens) == 0 {

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Provide at least one host token: "localhost", "*", an IP, or a resolvable name
  2. If the intent was 'all interfaces', pass "*" (or "0.0.0.0,::") rather than an empty string
  3. Default the config value before parsing: if strings.TrimSpace(hosts) == "" { hosts = "localhost" }

Example fix

// before
plan, err := netbind.NewPlan("") // or whatever wraps parseHostTokens

// after
plan, err := netbind.NewPlan("localhost")
// or "*" for all interfaces
Defensive patterns

Strategy: validation

Validate before calling

hosts := strings.TrimSpace(cfg.BindHosts)
if hosts == "" {
    hosts = "localhost" // or "*" for all interfaces
}
plan, err := netbind.NewPlan(hosts)

Prevention

When it happens

Trigger: Building a bind Plan from a host spec string that is "" or whitespace-only — e.g. a config hosts field left unset and defaulted to "" instead of a real value like "localhost".

Common situations: Optional bind-host config mapped verbatim to the parser; YAML null/empty scalar for the hosts key; tests passing an empty string for 'any host' when they meant "*" or "0.0.0.0".

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/eb5e16d624734b39. Report an issue: GitHub.