sipeed/picoclaw · error

host list contains an empty entry

Error message

host list contains an empty entry

What it means

parseHostToken rejects an individual comma element that is empty after trimming. A host list may be empty overall (different error) but may not contain blank entries: "localhost,,127.0.0.1", "a,b,", ",a" and "a, ,b" all fail here.

Source

Thrown at pkg/netbind/netbind.go:454

		}
		if _, ok := seen[token.key]; ok {
			continue
		}
		seen[token.key] = struct{}{}
		tokens = append(tokens, token)
	}

	if len(tokens) == 0 {
		return nil, errors.New("host cannot be empty")
	}

	return tokens, nil
}

func parseHostToken(raw string) (hostToken, error) {
	host := strings.TrimSpace(raw)
	if host == "" {
		return hostToken{}, errors.New("host list contains an empty entry")
	}

	if host == "*" {
		return hostToken{kind: tokenStar, canonical: "*", key: "*"}, nil
	}
	if strings.EqualFold(host, "localhost") {
		return hostToken{kind: tokenLocalhost, canonical: "localhost", key: "localhost"}, nil
	}

	trimmed := strings.Trim(host, "[]")
	if ip := net.ParseIP(trimmed); ip != nil {
		if ip4 := ip.To4(); ip4 != nil {
			canonical := ip4.String()
			kind := tokenIPv4
			if ip4.IsUnspecified() {
				kind = tokenIPv4Any
			}
			return hostToken{kind: kind, canonical: canonical, key: canonical}, nil

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Remove empty elements: keep only non-blank tokens before joining
  2. Fix the literal: "localhost,127.0.0.1" instead of "localhost,,127.0.0.1"
  3. Sanitize at the config layer: filter parts where strings.TrimSpace(part) != ""

Example fix

// before
hosts := strings.Join(cfg.Hosts, ",") // cfg.Hosts contains ""

// after
var clean []string
for _, h := range cfg.Hosts {
    if strings.TrimSpace(h) != "" { clean = append(clean, h) }
}
hosts := strings.Join(clean, ",")
Defensive patterns

Strategy: validation

Validate before calling

func sanitizeHostList(raw string) (string, error) {
    parts := strings.Split(raw, ",")
    keep := parts[:0]
    for _, p := range parts {
        if t := strings.TrimSpace(p); t != "" { keep = append(keep, t) }
    }
    if len(keep) == 0 { return "", errors.New("no hosts in list") }
    return strings.Join(keep, ","), nil
}

Prevention

When it happens

Trigger: Passing a comma-separated host spec with a leading/trailing comma, double commas, or whitespace-only entries between commas.

Common situations: Hosts list assembled by joining a slice containing empty strings; YAML flow sequence turned into a comma string with a trailing separator; copy-paste of "127.0.0.1, " from docs.

Related errors


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