{"record":{"id":"9bb962e16b07896e","repo":"chenhg5/cc-connect","slug":"read-existing-agy-hooks-s-w","errorCode":null,"errorMessage":"read existing Agy hooks %s: %w","messagePattern":"read existing Agy hooks (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/antigravity/permission_bridge.go","lineNumber":129,"sourceCode":"\tif err := mirrorDirectoryEntries(realConfigRoot, overlayConfigRoot, map[string]bool{\"config\": true}); err != nil {\n\t\treturn \"\", err\n\t}\n\trealConfigDir := filepath.Join(realConfigRoot, \"config\")\n\tif err := mirrorDirectoryEntries(realConfigDir, overlayConfigDir, map[string]bool{\"hooks.json\": true}); err != nil {\n\t\treturn \"\", err\n\t}\n\n\thooks := make(map[string]json.RawMessage)\n\thooksPath := filepath.Join(realConfigDir, \"hooks.json\")\n\tif data, err := os.ReadFile(hooksPath); err == nil {\n\t\tif err := json.Unmarshal(data, &hooks); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"parse existing Agy hooks %s: %w\", hooksPath, err)\n\t\t}\n\t\tif hooks == nil {\n\t\t\thooks = make(map[string]json.RawMessage)\n\t\t}\n\t} else if !os.IsNotExist(err) {\n\t\treturn \"\", fmt.Errorf(\"read existing Agy hooks %s: %w\", hooksPath, err)\n\t}\n\n\texecutable, err := os.Executable()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"resolve cc-connect executable for Agy hook: %w\", err)\n\t}\n\tbridgeHook, err := json.Marshal(map[string]any{\n\t\t\"PreToolUse\": []any{\n\t\t\tmap[string]any{\n\t\t\t\t\"matcher\": \"*\",\n\t\t\t\t\"hooks\": []any{\n\t\t\t\t\tmap[string]any{\n\t\t\t\t\t\t\"type\":    \"command\",\n\t\t\t\t\t\t\"command\": shellQuote(executable) + \" _agy-permission-hook\",\n\t\t\t\t\t\t\"timeout\": 86400,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/antigravity/permission_bridge.go#L111-L147","documentation":"createAgyConfigOverlay reads ~/.gemini/config/hooks.json to merge existing hooks into the overlay. If the read fails with any error other than NotExist (permission denied, I/O error, path is a directory), this wrapped error is returned.","triggerScenarios":"newAgyPermissionBridge → createAgyConfigOverlay when os.ReadFile on <home>/.gemini/config/hooks.json fails with EACCES, EISDIR, EIO, etc. (only ENOENT is tolerated).","commonSituations":"hooks.json owned by another user with restrictive permissions, hooks.json accidentally created as a directory, NFS/network home directories with stale handles, or SELinux/AppArmor denying read access.","solutions":["Check permissions: `ls -la ~/.gemini/config/hooks.json` and make it readable by the cc-connect user (chmod 600 with correct owner).","If hooks.json is a directory, remove it — it should be a regular file.","Verify no mandatory access control (SELinux/AppArmor) is blocking reads; restore appropriate labels/context.","On network home dirs, verify the mount is healthy and the file is accessible."],"exampleFix":"// before\n-rw------- root root ~/.gemini/config/hooks.json  # cc-connect runs as ccuser\n// after\nchown ccuser ~/.gemini/config/hooks.json && chmod 600 ~/.gemini/config/hooks.json","handlingStrategy":"validation","validationCode":"// shell: preflight readability of the real hooks file\n[ -r \"$HOME/.gemini/config/hooks.json\" ] && [ -f \"$HOME/.gemini/config/hooks.json\" ] \\\n  || echo \"hooks.json unreadable or a directory\"","typeGuard":null,"tryCatchPattern":"if err := startAntigravitySession(); err != nil && strings.Contains(err.Error(), \"read existing Agy hooks\") {\n    // inspect ownership/permissions of ~/.gemini/config/hooks.json, fix, retry\n}","preventionTips":["Run cc-connect as the same user that owns ~/.gemini.","Never replace hooks.json with a directory.","Check SELinux/AppArmor denials in audit logs when home dirs are on unusual mounts."],"tags":["filesystem","file-read","permissions","antigravity","go"],"backgroundTag":"file-read-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}