chenhg5/cc-connect · error
read config: %w
Error message
read config: %w
What it means
SaveProviderModel wraps any os.ReadFile failure on ConfigPath with 'read config: %w'. The file could not be read at all (missing, permission, or I/O error), so the surgical edit cannot proceed and the underlying OS error is preserved for diagnosis.
Source
Thrown at config/config.go:1218
func SaveActiveProvider(projectName, providerName string) error {
configMu.Lock()
defer configMu.Unlock()
return patchProjectAgentOption(projectName, "provider", providerName)
}
// SaveProviderModel persists the selected model for a provider in a project.
// It first looks in the project's inline providers, then falls back to
// global [[providers]] if the provider is referenced via provider_refs.
// Uses surgical text editing to preserve comments and unknown fields.
func SaveProviderModel(projectName, providerName, model string) error {
configMu.Lock()
defer configMu.Unlock()
if ConfigPath == "" {
return fmt.Errorf("config path not set")
}
data, err := os.ReadFile(ConfigPath)
if err != nil {
return fmt.Errorf("read config: %w", err)
}
raw := string(data)
cfg := &Config{}
if err := toml.Unmarshal(data, cfg); err != nil {
return fmt.Errorf("parse config: %w", err)
}
projectIdx := -1
for i := range cfg.Projects {
if cfg.Projects[i].Name == projectName {
projectIdx = i
break
}
}
if projectIdx < 0 {
return fmt.Errorf("project %q not found in config", projectName)
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Verify the path in the wrapped error exists: ls the exact path from ConfigPath
- Fix file permissions so the process user can read the file
- Correct the ConfigPath/--config value and retry
- Restore the config file from backup if it was deleted
Example fix
// before config.ConfigPath = "/etc/cc-connect/confg.toml" // typo // after config.ConfigPath = "/etc/cc-connect/config.toml"
Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(config.ConfigPath); err != nil {
return fmt.Errorf("config unreadable: %w", err)
} Try / catch
if err := config.SaveProviderModel(p, prov, model); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) { // wrapped by 'read config:'
log.Printf("fix path/permissions: %v", pe)
}
return err
} Prevention
- Check file existence/permissions at startup health checks
- Run the daemon as a user with read access to the config
- Guard the config file against deletion by cleanup scripts
When it happens
Trigger: os.ReadFile(ConfigPath) fails inside SaveProviderModel: file deleted/moved after startup, wrong ConfigPath value, insufficient read permission, or disk/IO error.
Common situations: Pointing the app at a non-existent config path; running the daemon as a user without read permission on the config; config removed by a cleanup script while the process is running.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/a38bd0e57878ad08.
Report an issue: GitHub.