netbirdio/netbird · error
failed to list profiles: %w
Error message
failed to list profiles: %w
What it means
ListProfiles delegates to the internal ServiceManager, which reads every profile config under configDir/profiles (plus the default profile) and merges the active state. The whole listing aborts on the first failure: an unreadable directory, an I/O error, or any single profile JSON file that cannot be parsed.
Source
Thrown at client/android/profile_manager.go:95
profilemanager.ActiveProfileStatePath = filepath.Join(configDir, "active_profile.json")
// Create ServiceManager with profiles/ subdirectory
// This avoids modifying the global ConfigDirOverride for profile listing
profilesDir := filepath.Join(configDir, profilesSubdir)
serviceMgr := profilemanager.NewServiceManagerWithProfilesDir(defaultConfigPath, profilesDir)
return &ProfileManager{
configDir: configDir,
serviceMgr: serviceMgr,
}
}
// ListProfiles returns all available profiles
func (pm *ProfileManager) ListProfiles() (*ProfileArray, error) {
// Use ServiceManager (looks in profiles/ directory, checks active_profile.json for IsActive)
internalProfiles, err := pm.serviceMgr.ListProfiles(androidUsername)
if err != nil {
return nil, fmt.Errorf("failed to list profiles: %w", err)
}
// Convert internal profiles to Android Profile type
var profiles []*Profile
for _, p := range internalProfiles {
profiles = append(profiles, &Profile{
ID: p.ID.String(),
Name: p.Name,
Email: pm.profileEmail(p.ID.String()),
IsActive: p.IsActive,
})
}
return &ProfileArray{items: profiles}, nil
}
// GetActiveProfile returns the currently active profile name
func (pm *ProfileManager) GetActiveProfile() (*Profile, error) {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Verify the configDir passed to NewProfileManager is the app-private files directory
- Inspect the JSON files under configDir/profiles and delete or fix any that are truncated or corrupt
- Ensure no other process writes the directory concurrently
- Call ListProfiles again after cleanup; a removed file is safe — the profile is recreated on next login
Defensive patterns
Strategy: fallback
Validate before calling
// Sanity-check the profiles directory before first use
if _, err := os.Stat(filepath.Join(configDir, "profiles")); err != nil && !os.IsNotExist(err) {
// permissions/I/O problem: fix before calling ListProfiles
} Try / catch
profiles, err := pm.ListProfiles()
if err != nil {
// fall back: treat as no extra profiles; offer the default profile and a login
profiles = nil
} Prevention
- Pass the app-private files dir as configDir; never shared storage
- Do not hand-edit profile JSON files
- Keep writes single-threaded through ProfileManager so files are never partially written
- On corrupt-file errors, inspect and prune configDir/profiles rather than retrying blindly
When it happens
Trigger: ProfileManager.ListProfiles() → serviceMgr.ListProfiles("android") fails when the profiles/ directory cannot be read (permissions, deleted), a profile .json file is corrupt, or a file read errors mid-scan.
Common situations: Corrupt config from an interrupted WriteOutConfig (app killed mid-save), configDir pointing at the wrong path, files restored from backup with wrong ownership, app data partially cleared.
Related errors
- failed to read profile config: %w
- failed to get active profile: %w
- failed to resolve active profile %q: %w
- failed to switch profile: %w
- profile '%s' does not exist
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/3caabffa7b02ba69.
Report an issue: GitHub.