{"record":{"id":"b90a8b51d2782515","repo":"juanfont/headscale","slug":"w-missing-in-q","errorCode":null,"errorMessage":"%w: missing @ in %q","messagePattern":"%w: missing @ in %q","errorType":"validation","errorClass":"ErrInvalidLocalpart","httpStatus":null,"severity":"error","filePath":"hscontrol/policy/v2/types.go","lineNumber":3081,"sourceCode":"\t_, err := u.ParseLocalpart()\n\n\treturn err == nil\n}\n\n// ParseLocalpart validates and extracts the domain from a localpart: entry.\n// The expected format is localpart:*@<domain>.\n// Returns the domain part or an error if the format is invalid.\nfunc (u SSHUser) ParseLocalpart() (string, error) {\n\tif !u.IsLocalpart() {\n\t\treturn \"\", fmt.Errorf(\"%w: missing prefix %q in %q\", ErrInvalidLocalpart, SSHUserLocalpartPrefix, u)\n\t}\n\n\tpattern := strings.TrimPrefix(string(u), SSHUserLocalpartPrefix)\n\n\t// Must be *@<domain>\n\tatIdx := strings.LastIndex(pattern, \"@\")\n\tif atIdx < 0 {\n\t\treturn \"\", fmt.Errorf(\"%w: missing @ in %q\", ErrInvalidLocalpart, u)\n\t}\n\n\tlocalPart := pattern[:atIdx]\n\tdomain := pattern[atIdx+1:]\n\n\tif localPart != \"*\" {\n\t\treturn \"\", fmt.Errorf(\"%w: local part must be *, got %q in %q\", ErrInvalidLocalpart, localPart, u)\n\t}\n\n\tif domain == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%w: empty domain in %q\", ErrInvalidLocalpart, u)\n\t}\n\n\treturn domain, nil\n}\n\n// MarshalJSON marshals the [SSHUser] to JSON.\nfunc (u SSHUser) MarshalJSON() ([]byte, error) {","sourceCodeStart":3063,"sourceCodeEnd":3099,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/policy/v2/types.go#L3063-L3099","documentation":"Error \"%w: missing @ in %q\" thrown in juanfont/headscale.","triggerScenarios":"Thrown at hscontrol/policy/v2/types.go:3081 when the library encounters an invalid state.","commonSituations":"A username entry in the policy lacks the required '@' domain part. Use full user identifiers like user@example.com.","solutions":["Inspect the wrapped error for the underlying cause and correct the failing condition (); retry the operation after fixing the input, configuration, or environment."],"exampleFix":"Inspect the wrapped error for the underlying cause and correct the failing condition (); retry the operation after fixing the input, configuration, or environment.","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}