{"record":{"id":"48ccaa7133e72163","repo":"chenhg5/cc-connect","slug":"resolve-home-directory-for-agy-permission-bridge","errorCode":null,"errorMessage":"resolve home directory for Agy permission bridge: %w","messagePattern":"resolve home directory for Agy permission bridge: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/antigravity/permission_bridge.go","lineNumber":100,"sourceCode":"\t\tctx:       bridgeCtx,\n\t\tcancel:    cancel,\n\t\tlistener:  listener,\n\t\taddress:   listener.Addr().String(),\n\t\ttoken:     base64.RawURLEncoding.EncodeToString(tokenBytes),\n\t\trootDir:   rootDir,\n\t\tconfigDir: configDir,\n\t\tevents:    events,\n\t\tpending:   make(map[string]chan core.PermissionResult),\n\t}\n\tbridge.wg.Add(1)\n\tgo bridge.acceptLoop()\n\treturn bridge, nil\n}\n\nfunc createAgyConfigOverlay(rootDir string) (string, error) {\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"resolve home directory for Agy permission bridge: %w\", err)\n\t}\n\t// Antigravity currently stores its CLI state under .gemini and exposes it\n\t// through the --gemini_dir compatibility flag.\n\trealConfigRoot := filepath.Join(homeDir, \".gemini\")\n\toverlayConfigRoot := filepath.Join(rootDir, \"agy-config\")\n\toverlayConfigDir := filepath.Join(overlayConfigRoot, \"config\")\n\tif err := os.MkdirAll(overlayConfigDir, 0o700); err != nil {\n\t\treturn \"\", fmt.Errorf(\"create Agy permission overlay: %w\", err)\n\t}\n\n\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","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/antigravity/permission_bridge.go#L82-L118","documentation":"createAgyConfigOverlay resolves the current user's home directory (os.UserHomeDir) to locate the real ~/.gemini config root for the permission bridge overlay. If the home directory cannot be resolved, it returns this wrapped error and the bridge is not created.","triggerScenarios":"newAgyPermissionBridge → createAgyConfigOverlay when os.UserHomeDir fails: HOME (and USERPROFILE on Windows) unset for the current user.","commonSituations":"Running cc-connect under systemd or a daemon with a scrubbed environment (no HOME), running as a setuid/service account without a home dir, or containers running as a UID with no passwd entry.","solutions":["Set the HOME environment variable for the process (e.g. Environment=HOME=/home/user in the systemd unit).","Ensure the user the daemon runs as exists in /etc/passwd with a valid home directory.","If using systemd, add SetEnvironment=HOME=%h or run with a Login shell context.","Verify os.UserHomeDir works for the same user: `sudo -u <user> sh -c 'echo $HOME'`."],"exampleFix":"// before: systemd unit without HOME\n[Service]\nExecStart=/usr/local/bin/cc-connect\n// after\n[Service]\nEnvironment=HOME=/home/ccuser\nExecStart=/usr/local/bin/cc-connect","handlingStrategy":"validation","validationCode":"// Go: check HOME is resolvable before starting the daemon\nif os.Getenv(\"HOME\") == \"\" && runtime.GOOS != \"windows\" {\n    return errors.New(\"HOME is not set; antigravity bridge requires it\")\n}","typeGuard":null,"tryCatchPattern":"if err := startAntigravitySession(); err != nil && strings.Contains(err.Error(), \"resolve home directory\") {\n    // log hint: set HOME/USERPROFILE for the service user\n}","preventionTips":["Always set HOME explicitly in systemd units / Dockerfiles / CI containers.","Create service users with a real home directory (useradd -m).","Document required env vars for headless deployments."],"tags":["environment","home-directory","antigravity","go"],"backgroundTag":"missing-env-var","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}