{"record":{"id":"345d061adf37c9f6","repo":"mislav/hub","slug":"property-name-is-must-be-string-but-got-v","errorCode":null,"errorMessage":"property name is must be string but got %#v","messagePattern":"property name is must be string but got %#v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"github/config_decoder.go","lineNumber":56,"sourceCode":"\t}\n\n\tfor _, hostEntry := range yc {\n\t\tv, ok := hostEntry.Value.([]interface{})\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"value of host entry is must be array but got %#v\", hostEntry.Value)\n\t\t}\n\t\tif len(v) < 1 {\n\t\t\tcontinue\n\t\t}\n\t\thostName, ok := hostEntry.Key.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"host name is must be string but got %#v\", hostEntry.Key)\n\t\t}\n\t\thost := &Host{Host: hostName}\n\t\tfor _, prop := range v[0].(yaml.MapSlice) {\n\t\t\tpropName, ok := prop.Key.(string)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"property name is must be string but got %#v\", prop.Key)\n\t\t\t}\n\t\t\tswitch propName {\n\t\t\tcase \"user\":\n\t\t\t\thost.User, ok = prop.Value.(string)\n\t\t\tcase \"oauth_token\":\n\t\t\t\thost.AccessToken, ok = prop.Value.(string)\n\t\t\tcase \"protocol\":\n\t\t\t\thost.Protocol, ok = prop.Value.(string)\n\t\t\tcase \"unix_socket\":\n\t\t\t\thost.UnixSocket, ok = prop.Value.(string)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"%s is must be string but got %#v\", propName, prop.Value)\n\t\t\t}\n\t\t}\n\t\tc.Hosts = append(c.Hosts, host)\n\t}\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/mislav/hub/blob/5c547ed804368763064e51f3990851e267e88edd/github/config_decoder.go#L38-L74","documentation":"Within a host's property MapSlice, every property key must be a string to be matched against known fields (user, oauth_token, protocol, unix_socket). A non-string key fails the type assertion and Decode returns this error naming the offending key.","triggerScenarios":"A property inside a host entry whose key is a numeric, boolean, or null YAML scalar instead of a string, e.g. `- 123: value` under a host.","commonSituations":"Corrupted or hand-mangled config files; paste errors adding junk lines; unquoted keys parsed by YAML as non-string scalars.","solutions":["Ensure all property keys under each host are plain string keys (user, oauth_token, protocol, unix_socket).","Quote ambiguous keys and remove non-property entries from the host list.","Regenerate ~/.config/hub via interactive hub login if the file is corrupted."],"exampleFix":"// before\ngithub.com:\n- user: octocat\n  2023: junk\n// after\ngithub.com:\n- user: octocat\n  oauth_token: xxxx","handlingStrategy":"validation","validationCode":"var raw map[string][]interface{}\nyaml.Unmarshal(data, &raw)\nfor _, entries := range raw {\n    for _, e := range entries {\n        m, ok := e.(yaml.MapSlice)\n        if !ok { continue }\n        for _, p := range m {\n            if _, ok := p.Key.(string); !ok {\n                log.Fatalf(\"property key %v is not a string\", p.Key)\n            }\n        }\n    }\n}","typeGuard":"func isStringPropKey(k interface{}) bool {\n    _, ok := k.(string)\n    return ok\n}","tryCatchPattern":"if err := cfg.Decode(data); err != nil {\n    if strings.Contains(err.Error(), \"property name is must be string\") {\n        return fmt.Errorf(\"non-string property key in hub config: %w\", err)\n    }\n    return err\n}","preventionTips":["Only use known string keys: user, oauth_token, protocol, unix_socket","Remove junk/garbage lines introduced by paste errors","Regenerate the config with interactive login if it becomes corrupted"],"tags":["yaml","configuration","decoding","type-error"],"backgroundTag":"config-schema-validation-failed","analyzedSha":"5c547ed804368763064e51f3990851e267e88edd","analyzedAt":"2026-09-01T03:34:15.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}