yorukot/superfile · error
could not read user's theme file(%s), err : %w
Error message
could not read user's theme file(%s), err : %w
What it means
LoadUserTheme reads a user theme file from disk and wraps any os.ReadFile failure with this message. It is thrown when the theme file cannot be read at all (as opposed to failing to parse). The wrapped error (%w) contains the underlying os error such as ENOENT or EACCES.
Source
Thrown at src/internal/common/load_config.go:215
utils.PrintfAndExitf("Unexpected error while reading default theme file : %v. Exiting...", err)
}
}
// Validations
if len(Theme.GradientColor) != RequiredGradientColorCount {
utils.PrintlnAndExit(
LoadThemeError(
"gradient_color",
"Gradient color must contain exactly two values.",
),
)
}
}
func LoadUserTheme(themeFile string, obj *ThemeType) error {
data, err := os.ReadFile(themeFile)
if err != nil {
return fmt.Errorf("could not read user's theme file(%s), err : %w", themeFile, err)
}
if err = toml.Unmarshal(data, obj); err != nil {
return fmt.Errorf("could not unmarshal user's theme file(%s) : %w", themeFile, err)
}
return nil
}
// LoadAllDefaultConfig : Load all default configurations from embedded superfile_config folder into global
// configurations variables and write theme files if its needed.
func LoadAllDefaultConfig(content embed.FS) {
err := LoadConfigStringGlobals(content)
if err != nil {
slog.Error("Could not load default config from embed FS", "error", err)
return
}
currentThemeVersion, err := os.ReadFile(variable.ThemeFileVersion)
if err != nil && !os.IsNotExist(err) {View on GitHub (pinned to b72f550bc6)
Solutions
- Check that the theme file path printed in the error actually exists (ls the path).
- Set the theme in config to a name matching an existing file in the themes directory, or create the file.
- Fix file permissions (chmod 644) or ownership on the theme file.
- Verify the path is a regular file, not a directory.
Example fix
// before theme = 'my-custom-theme' // file never created // after theme = 'catppuccin' // matches ~/.config/superfile/theme/catppuccin.toml
Defensive patterns
Strategy: validation
Validate before calling
if st, err := os.Stat(themeFile); err != nil {
return fmt.Errorf("theme file %q not accessible: %w", themeFile, err)
} else if st.IsDir() {
return fmt.Errorf("theme path %q is a directory", themeFile)
} Type guard
func themeFileReadable(path string) bool {
f, err := os.Open(path)
if err != nil { return false }
f.Close()
return true
} Try / catch
if err := common.LoadUserTheme(themeFile, &theme); err != nil {
var pErr *fs.PathError
if errors.As(err, &pErr) && errors.Is(pErr.Err, fs.ErrNotExist) {
log.Warnf("theme %q missing, using default", themeFile)
return common.LoadDefaultTheme()
}
return err
} Prevention
- Ship/verify default theme files on first run before referencing them by name.
- Validate the theme path exists at config-load time, not deep in the UI.
- Never construct theme paths by string concatenation without filepath.Join.
- Watch theme dirs for external deletions if you cache the config.
When it happens
Trigger: LoadThemeFile calls LoadUserTheme(themeFile, obj) and os.ReadFile(themeFile) returns an error: the file does not exist, permission is denied, or the path is a directory.
Common situations: User set a custom theme name in config but never created the corresponding ~/.config/superfile/theme/<name>.toml file; a typo in the theme path; file deleted or moved by another tool; restrictive file permissions after a dotfiles sync.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- could not unmarshal user's theme file(%s) : %w
- error encoding data : %w
- failed to create directory %s: %w
- failed to create file %s: %w
AI-assisted analysis of yorukot/superfile@b72f550bc6 (2026-09-01).
Data as JSON: /api/errors/83707345abecc3f0.
Report an issue: GitHub.