mislav/hub · error

host name is must be string but got %#v

Error message

host name is must be string but got %#v

What it means

While decoding a host entry, the decoder casts each top-level key to a string to use as the host name. If the key is another YAML scalar type (number, boolean, null), the cast fails and this error is returned. It ensures host names in the config are proper strings.

Source

Thrown at github/config_decoder.go:50

	yc := yaml.MapSlice{}
	err = yaml.Unmarshal(d, &yc)

	if err != nil {
		return err
	}

	for _, hostEntry := range yc {
		v, ok := hostEntry.Value.([]interface{})
		if !ok {
			return fmt.Errorf("value of host entry is must be array but got %#v", hostEntry.Value)
		}
		if len(v) < 1 {
			continue
		}
		hostName, ok := hostEntry.Key.(string)
		if !ok {
			return fmt.Errorf("host name is must be string but got %#v", hostEntry.Key)
		}
		host := &Host{Host: hostName}
		for _, prop := range v[0].(yaml.MapSlice) {
			propName, ok := prop.Key.(string)
			if !ok {
				return fmt.Errorf("property name is must be string but got %#v", prop.Key)
			}
			switch propName {
			case "user":
				host.User, ok = prop.Value.(string)
			case "oauth_token":
				host.AccessToken, ok = prop.Value.(string)
			case "protocol":
				host.Protocol, ok = prop.Value.(string)
			case "unix_socket":
				host.UnixSocket, ok = prop.Value.(string)
			}
			if !ok {

View on GitHub (pinned to 5c547ed804)

Solutions

  1. Quote the host key in the YAML: `"github.example.com":` so it always parses as a string.
  2. Remove any non-host keys accidentally present at the top level of ~/.config/hub.
  3. Check indentation — a misindented property may become a top-level key.

Example fix

// before (parses as boolean)
no:
- user: octocat
// after
"no.example.com":
- user: octocat
Defensive patterns

Strategy: validation

Validate before calling

var raw map[interface{}]interface{}
yaml.Unmarshal(data, &raw)
for k := range raw {
    if _, ok := k.(string); !ok {
        log.Fatalf("top-level key %v is not a string; quote it in YAML", k)
    }
}

Type guard

func isStringKey(k interface{}) bool {
    _, ok := k.(string)
    return ok
}

Try / catch

if err := cfg.Decode(data); err != nil {
    if strings.Contains(err.Error(), "host name is must be string") {
        return fmt.Errorf("quote non-string host keys in ~/.config/hub: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A configs file containing a host key that is not a string, e.g. a bare number (`12345:`) or boolean (`true:`) at top level, or YAML that parses a domain into a non-string scalar.

Common situations: Unquoted hostnames that YAML interprets as booleans or numbers (classic YAML Norway problem with `no:`), stray indentation turning text into a key of the wrong type.

Related errors


AI-assisted analysis of mislav/hub@5c547ed804 (2026-09-01). Data as JSON: /api/errors/6a722b115ad20957. Report an issue: GitHub.