chenhg5/cc-connect · error

open cc-switch db: %w

Error message

open cc-switch db: %w

What it means

queryCCSwitchDB fails to open the cc-switch SQLite database file in read-only mode (mode=ro) and wraps the driver error with this message. sql.Open with a sqlite driver typically errors here on an invalid DSN/path or missing/unreadable file (depending on driver version), so import or listing of cc-switch providers cannot proceed.

Source

Thrown at cmd/cc-connect/provider.go:319

	if imported > 0 {
		fmt.Println("\nActivate a provider with: /provider switch <name> in chat")
	}
}

type ccSwitchRow struct {
	ID             string `json:"id"`
	AppType        string `json:"app_type"`
	Name           string `json:"name"`
	SettingsConfig string `json:"settings_config"`
	IsCurrent      int    `json:"is_current"`
}

// queryCCSwitchDB opens the cc-switch SQLite database and returns provider rows.
// appTypeFilter can be empty (return all) or "claude"/"codex".
func queryCCSwitchDB(dbPath, appTypeFilter string) ([]ccSwitchRow, error) {
	db, err := sql.Open("sqlite", dbPath+"?mode=ro")
	if err != nil {
		return nil, fmt.Errorf("open cc-switch db: %w", err)
	}
	defer db.Close()

	query := "SELECT id, app_type, name, settings_config, is_current FROM providers"
	var args []any
	if appTypeFilter != "" {
		query += " WHERE app_type = ?"
		args = append(args, appTypeFilter)
	}

	rows, err := db.Query(query, args...)
	if err != nil {
		return nil, fmt.Errorf("query cc-switch db: %w", err)
	}
	defer rows.Close()

	var result []ccSwitchRow
	for rows.Next() {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify the cc-switch DB path exists: `ls -l ~/.cc-switch/...db` and correct dbPath.
  2. Check file read permissions for the process user.
  3. Confirm the sqlite driver is imported (blank import) so sql.Open does not fail with unknown driver.
  4. Ensure the path contains no stray characters; the code appends `?mode=ro` so dbPath itself must be a plain file path.
  5. If the app is not installed, install cc-switch or skip the import.

Example fix

// before
db, err := sql.Open("sqlite", dbPath+"?mode=ro")
// after
if _, err := os.Stat(dbPath); err != nil {
    return nil, fmt.Errorf("cc-switch db not found at %s (is cc-switch installed?): %w", dbPath, err)
}
db, err := sql.Open("sqlite", dbPath+"?mode=ro")
Defensive patterns

Strategy: validation

Validate before calling

func ccSwitchDBReady(dbPath string) error {
    fi, err := os.Stat(dbPath)
    if err != nil { return fmt.Errorf("cc-switch db missing: %w", err) }
    if fi.IsDir() { return fmt.Errorf("%s is a directory", dbPath) }
    if fi.Mode().Perm()&0400 == 0 { return fmt.Errorf("%s not readable", dbPath) }
    return nil
}

Try / catch

rows, err := queryCCSwitchDB(dbPath, filter)
if err != nil {
    if strings.Contains(err.Error(), "open cc-switch db") {
        return fmt.Errorf("cannot read cc-switch database at %s: %w (install cc-switch or fix the path)", dbPath, err)
    }
    return err
}

Prevention

When it happens

Trigger: runProviderImport or listCCSwitchProvidersForWeb calls queryCCSwitchDB with a dbPath that does not exist, is a directory, has wrong permissions, or a malformed DSN suffix; the sqlite driver is not registered (blank import missing).

Common situations: cc-switch app never installed so its DB file is absent; user passed the wrong path to the cc-switch database; database located in another user's home directory without read access; forgotten `_ "modernc.org/sqlite"` import.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/b7489a89287f57f7. Report an issue: GitHub.