{"record":{"id":"eea7447685490db8","repo":"gofiber/fiber","slug":"domain-pattern-s-contains-empty-parameter-name","errorCode":null,"errorMessage":"Domain pattern '%s' contains empty parameter name at position %d","messagePattern":"Domain pattern '(.+?)' contains empty parameter name at position (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"domain.go","lineNumber":94,"sourceCode":"\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' has %d parts, which exceeds the maximum of %d\",\n\t\t\tpattern, len(parts), maxDomainParts))\n\t}\n\n\tm := domainMatcher{\n\t\tparts:    make([]string, len(parts)),\n\t\tnumParts: len(parts),\n\t}\n\n\tfor i, part := range parts {\n\t\t// Validate no empty labels (e.g., \"example..com\" is invalid)\n\t\tif part == \"\" {\n\t\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' contains empty label at position %d\", pattern, i))\n\t\t}\n\n\t\tif part[0] == ':' {\n\t\t\t// Validate parameter name is not empty\n\t\t\tif len(part) == 1 {\n\t\t\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' contains empty parameter name at position %d\", pattern, i))\n\t\t\t}\n\t\t\tparamName := part[1:]\n\t\t\t// Validate parameter name contains only ASCII-safe characters (a-z, A-Z, 0-9, underscore, hyphen).\n\t\t\t// Using explicit ASCII ranges rather than unicode.IsLetter/IsDigit to reject non-ASCII\n\t\t\t// characters that are invalid in DNS names.\n\t\t\tfor _, ch := range paramName {\n\t\t\t\tif !isASCIIAlphanumeric(ch) && ch != '_' && ch != '-' {\n\t\t\t\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' contains invalid parameter name '%s' with character '%c'\", pattern, paramName, ch))\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.paramIdx = append(m.paramIdx, i)\n\t\t\tm.paramNames = append(m.paramNames, paramName) // preserve original case\n\t\t\tm.parts[i] = part                              // keep \":param\" marker for matching\n\t\t} else {\n\t\t\t// Only lowercase constant labels (RFC 4343)\n\t\t\t// Enforce RFC 1035 per-label length limit (63 characters)\n\t\t\tif len(part) > 63 {\n\t\t\t\tpanic(fmt.Sprintf(\"Domain pattern '%s' has label '%s' exceeding RFC 1035 limit of 63 characters (%d chars)\",","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/domain.go#L76-L112","documentation":"Inside parseDomainPattern, labels starting with ':' are treated as domain parameters (e.g. :tenant.example.com). A bare ':' (length 1) means the parameter name is missing, which would make the captured value unusable, so it panics with the label position.","triggerScenarios":"Passing a pattern like \":.example.com\" or \"example.:\" where a parameter label has no name.","commonSituations":"Typing a colon without the name; templating that emits ':' when a variable is empty; refactor that introduced a bare parameter marker.","solutions":["Always give parameter labels a name: \":tenant.example.com\" not \":.example.com\".","Validate parameter labels before registering: a label starting with ':' must have len > 1.","If the parameter is optional, omit the label entirely instead of emitting an empty parameter."],"exampleFix":"// before\napp.Domain(\":.example.com\")\n\n// after\napp.Domain(\":tenant.example.com\")","handlingStrategy":"validation","validationCode":"// Ensure every parameter label has a name\nfunc validateParamLabels(p string) error {\n    for i, label := range strings.Split(p, \".\") {\n        if label == \":\" {\n            return fmt.Errorf(\"empty parameter name at position %d\", i)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always name parameter labels (:tenant, not :).","Validate templated patterns before registering them.","Document the parameter-label syntax for route authors."],"tags":["routing","domain","validation","parameters","startup"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}