chenhg5/cc-connect · error
read Agy config directory %s: %w
Error message
read Agy config directory %s: %w
What it means
mirrorDirectoryEntries wraps any error from os.ReadDir on the antigravity ('Agy') source config directory. It is thrown when the directory exists but cannot be read (permissions, I/O error, or source is a file, not a directory). A non-existent directory is intentionally treated as success (returns nil), so this error indicates the directory exists but is unreadable.
Source
Thrown at agent/antigravity/permission_bridge.go:172
data, err := json.MarshalIndent(hooks, "", " ")
if err != nil {
return "", fmt.Errorf("marshal Agy hooks overlay: %w", err)
}
data = append(data, '\n')
if err := os.WriteFile(filepath.Join(overlayConfigDir, "hooks.json"), data, 0o600); err != nil {
return "", fmt.Errorf("write Agy hooks overlay: %w", err)
}
return overlayConfigRoot, nil
}
func mirrorDirectoryEntries(sourceDir, targetDir string, skip map[string]bool) error {
entries, err := os.ReadDir(sourceDir)
if os.IsNotExist(err) {
return nil
}
if err != nil {
return fmt.Errorf("read Agy config directory %s: %w", sourceDir, err)
}
for _, entry := range entries {
if skip[entry.Name()] {
continue
}
source := filepath.Join(sourceDir, entry.Name())
target := filepath.Join(targetDir, entry.Name())
if err := os.Symlink(source, target); err != nil {
return fmt.Errorf("link Agy config %s: %w", source, err)
}
}
return nil
}
func shellQuote(value string) string {
return "'" + strings.ReplaceAll(value, "'", "'\"'\"'") + "'"
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Check the directory is readable by the current user: ls -la <dir> and fix ownership/permissions (chmod/chown).
- Verify the path is actually a directory, not a file: file <dir>.
- If the directory should be optional/empty, ensure it exists with correct permissions or remove the stale file so IsNotExist handling applies.
- Inspect the wrapped cause (%w) in the message for the underlying OS error.
Example fix
// before: source is a stale file $ rm ~/.antigravity && mkdir ~/.antigravity // after $ mkdir -p ~/.antigravity && chmod 700 ~/.antigravity
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(sourceDir)
if err != nil || !info.IsDir() {
// directory missing or not a directory — fix perms or recreate
}
if info != nil && info.IsDir() {
if f, err := os.Open(sourceDir); err != nil { /* unreadable */ } else { f.Close() }
} Try / catch
if err := createAgyConfigOverlay(...); err != nil && strings.HasPrefix(err.Error(), "read Agy config directory") {
slog.Warn("agy config dir unreadable, skipping overlay", "err", err)
} Prevention
- Run cc-connect as the same user that owns the antigravity config directory.
- Check that the source path is a directory before overlay creation.
- Monitor filesystem health on network mounts.
When it happens
Trigger: os.ReadDir(sourceDir) fails with an error that is not os.IsNotExist while creating the agy config overlay via createAgyConfigOverlay. E.g. the source dir exists but the process lacks read permission, the path is a regular file, or a disk I/O error occurs.
Common situations: Running cc-connect as a user that cannot read ~/.antigravity (or similar) config owned by another user; a stale file replaced the config directory; NFS/readonly filesystem failures.
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
- create Agy permission overlay: %w
- read existing Agy hooks %s: %w
- write Agy hooks overlay: %w
- link Agy config %s: %w
- listen for Agy permission hooks: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/467387e6bbc5f34b.
Report an issue: GitHub.