{"record":{"id":"4cfea66d7096da2a","repo":"ginuerzh/gost","slug":"hosts-list-must-look-like-google-pl-google-com-g","errorCode":null,"errorMessage":"hosts list must look like google.pl,*.google.com given: %s","messagePattern":"hosts list must look like google\\.pl,\\*\\.google\\.com given: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"permissions.go","lineNumber":159,"sourceCode":"\t}\n\n\tperms := strings.Split(s, \" \")\n\n\tfor _, perm := range perms {\n\t\tparts := strings.Split(perm, \":\")\n\n\t\tswitch len(parts) {\n\t\tcase 3:\n\t\t\tactions, err := ParseStringSet(parts[0])\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"action list must look like connect,bind given: %s\", parts[0])\n\t\t\t}\n\n\t\t\thosts, err := ParseStringSet(parts[1])\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"hosts list must look like google.pl,*.google.com given: %s\", parts[1])\n\t\t\t}\n\n\t\t\tports, err := ParsePortSet(parts[2])\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"ports list must look like 80,8000-9000, given: %s\", parts[2])\n\t\t\t}\n\n\t\t\tpermission := Permission{Actions: *actions, Hosts: *hosts, Ports: *ports}\n\n\t\t\t*ps = append(*ps, permission)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"permission must have format [actions]:[hosts]:[ports] given: %s\", perm)\n\t\t}\n\t}\n\n\treturn ps, nil\n}","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/permissions.go#L141-L177","documentation":"ParsePermissions validates each permission entry of the form [actions]:[hosts]:[ports]. The hosts segment must be a non-empty comma-separated string; when ParseStringSet rejects it (most commonly because it is empty), the parser wraps the failure in this error and aborts, returning no Permissions at all. This is a fail-fast config validation error, not a runtime condition.","triggerScenarios":"Calling ParsePermissions with a permission whose middle colon-separated field is empty or invalid, e.g. \"connect::80\" — a permission token whose parts[1] is empty fails ParseStringSet (\"cannot be empty\").","commonSituations":"Gost config files or command-line permission flags with typos: a colon typo, double spaces between permissions (strings.Split on a single space yields empty tokens), trailing colons, or an empty hosts field like \"connect::443\" pasted from documentation.","solutions":["Check the permission string at permissions.go:159 — the hosts segment (parts[1]) must be a non-empty comma-separated list like google.pl,*.google.com","Fix malformed input: replace \"connect::80\" with \"connect:google.pl:80\"","Collapse double spaces in the permissions string; ParsePermissions splits on a single space so extra spaces introduce empty tokens that fail parsing","Validate the format with a regex before calling ParsePermissions"],"exampleFix":"// before\nperms, err := gost.ParsePermissions(\"connect::8080\")\n// after\nperms, err := gost.ParsePermissions(\"connect:*.example.com:8080\")","handlingStrategy":"validation","validationCode":"func validPerms(s string) bool {\n    for _, perm := range strings.Fields(s) {\n        parts := strings.Split(perm, \":\")\n        if len(parts) != 3 || parts[0] == \"\" || parts[1] == \"\" {\n            return false\n        }\n    }\n    return true\n}\nif !validPerms(input) { return errors.New(\"bad permissions string\") }","typeGuard":"func isNonEmptyStringSet(s string) bool { return s != \"\" }","tryCatchPattern":"perms, err := gost.ParsePermissions(input)\nif err != nil {\n    if strings.Contains(err.Error(), \"hosts list must look like\") {\n        log.Fatalf(\"bad hosts segment in permission %q: %v\", input, err)\n    }\n    return err\n}","preventionTips":["Always fill all three segments actions:hosts:ports; never leave the hosts field empty","Normalize whitespace (collapse double spaces) before parsing — ParsePermissions splits on single spaces","Add a startup smoke test that calls ParsePermissions on every configured permission string"],"tags":["config","parsing","validation","gost"],"backgroundTag":"config-parse-error","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}