netbirdio/netbird · error
failed to add profile: %w
Error message
failed to add profile: %w
What it means
AddProfile sanitizes the display name (rejects empty-after-trim, invalid UTF-8, and names over 128 runes), generates a fresh hex ID, and writes the new profile config into profiles/. The error wraps either that name validation failure or the I/O failure of creating the file/directory.
Source
Thrown at client/android/profile_manager.go:166
// ServiceManager uses active_profile.json
err := pm.serviceMgr.SetActiveProfileState(&profilemanager.ActiveProfileState{
ID: profilemanager.ID(id),
Username: androidUsername,
})
if err != nil {
return fmt.Errorf("failed to switch profile: %w", err)
}
log.Infof("switched to profile: %s", id)
return nil
}
// AddProfile creates a new profile
func (pm *ProfileManager) AddProfile(profileName string) error {
// Use ServiceManager (creates profile in profiles/ directory)
profile, err := pm.serviceMgr.AddProfile(profileName, androidUsername)
if err != nil {
return fmt.Errorf("failed to add profile: %w", err)
}
log.Infof("created new profile: %s", profile.ID)
return nil
}
// LogoutProfile logs out from a profile (clears authentication)
func (pm *ProfileManager) LogoutProfile(id string) error {
configPath, err := pm.getProfileConfigPath(id)
if err != nil {
return err
}
if !profilemanager.IsValidProfileFilenameStem(profilemanager.ID(id)) {
return fmt.Errorf("id '%s' is not valid", id)
}
// Check if profile existsView on GitHub (pinned to 93e97f4bf1)
Solutions
- Validate the name client-side before calling: non-empty after trim, at most 128 characters
- Retry with the trimmed name
- If the name is valid, check that profiles/ is creatable/writable and free space exists
Example fix
// before
pm.AddProfile(userInput) // "" or a 200-char string fails
// after
name := strings.TrimSpace(userInput)
if name == "" || utf8.RuneCountInString(name) > 128 {
// reject in the UI before calling
}
pm.AddProfile(name) Defensive patterns
Strategy: validation
Validate before calling
name := strings.TrimSpace(input)
if name == "" || utf8.RuneCountInString(name) > 128 {
// reject in the UI before calling AddProfile
} Type guard
func validProfileName(s string) bool {
if !utf8.ValidString(s) {
return false
}
s = strings.TrimSpace(s)
return s != "" && utf8.RuneCountInString(s) <= 128
} Try / catch
if err := pm.AddProfile(name); err != nil {
if validProfileName(strings.TrimSpace(name)) {
// name was fine → I/O problem: check profiles/ writability and free space
} else {
// validation problem: fix the input
}
} Prevention
- Trim and cap names at 128 characters in the UI
- Disable the confirm button while the name field is empty
- Reject pasted control-character-only input before it reaches the API
When it happens
Trigger: AddProfile(profileName) with a name that is empty, only whitespace/control characters after stripping, not valid UTF-8, or longer than 128 characters; or a profiles/ directory that cannot be created or written.
Common situations: UI passing an empty string when the user confirms the dialog too early, a pasted 129+ character name, storage full at creation time.
Related errors
- id '%s' is not valid
- failed to rename profile: %w
- id %q is not valid
- failed to list profiles: %w
- failed to get active profile: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/00308aa3b6d702fa.
Report an issue: GitHub.