netbirdio/netbird · error
failed to switch profile: %w
Error message
failed to switch profile: %w
What it means
SwitchProfile persists the new active profile by marshalling ActiveProfileState and writing active_profile.json. The wrapped error comes from that write path — encoding or I/O failure — not from validating the target profile: the id is stored as given and existence of the profile is not checked here.
Source
Thrown at client/android/profile_manager.go:154
// an unresolvable path degrades to "" rather than an error.
func (pm *ProfileManager) profileEmail(id string) string {
configPath, err := pm.getProfileConfigPath(id)
if err != nil {
return ""
}
return readProfileEmail(configPath)
}
// SwitchProfile switches to a different profile
func (pm *ProfileManager) SwitchProfile(id string) error {
// Use ServiceManager to stay consistent with ListProfiles
// 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
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Free device storage and retry the switch
- Ensure configDir is the app-private files dir and writable by the app
- Retry once the I/O condition clears; the state file is rewritten wholesale each switch
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the state directory is writable before offering profile switching
if f, err := os.Create(filepath.Join(configDir, ".probe")); err != nil {
// storage problem: surface it instead of failing inside SwitchProfile
} else { f.Close(); os.Remove(f.Name()) } Try / catch
if err := pm.SwitchProfile(id); err != nil {
// I/O failure writing active_profile.json: free space / verify permissions, then retry;
// the previous active state (if any) remains on disk, so the UI stays consistent
} Prevention
- Keep device storage from filling completely
- Route all profile switches through one component to avoid concurrent writes
- Switch using ids from ListProfiles so the stored state always points at a real profile
When it happens
Trigger: SetActiveProfileState fails when configDir is unwritable, the disk is full, an existing active_profile.json cannot be overwritten, or the state file sits on read-only storage.
Common situations: Device storage exhausted, app-private directory permissions disturbed by backup/restore tooling, two components switching profiles concurrently.
Related errors
- failed to list profiles: %w
- failed to get active profile: %w
- failed to resolve active profile %q: %w
- profile '%s' does not exist
- failed to read profile config: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/aca14c6e579603c6.
Report an issue: GitHub.