{"record":{"id":"d4be506d0f7ad0d0","repo":"chenhg5/cc-connect","slug":"pi-cannot-determine-settings-path","errorCode":null,"errorMessage":"pi: cannot determine settings path","messagePattern":"pi: cannot determine settings path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/pi/pi.go","lineNumber":429,"sourceCode":"\tdir := piSettingsDir()\n\tif dir == \"\" {\n\t\treturn \"\"\n\t}\n\treturn filepath.Join(dir, \"settings.json\")\n}\n\n// piSettings represents the structure of pi's settings.json relevant fields.\ntype piSettings struct {\n\tEnabledModels  []string `json:\"enabledModels\"`\n\tDefaultModel   string   `json:\"defaultModel\"`\n\tDefaultProvider string  `json:\"defaultProvider\"`\n}\n\n// readSettings reads and parses pi's settings.json.\nfunc readSettings() (*piSettings, error) {\n\tpath := settingsPath()\n\tif path == \"\" {\n\t\treturn nil, fmt.Errorf(\"pi: cannot determine settings path\")\n\t}\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"pi: read settings: %w\", err)\n\t}\n\tvar s piSettings\n\tif err := json.Unmarshal(data, &s); err != nil {\n\t\treturn nil, fmt.Errorf(\"pi: parse settings: %w\", err)\n\t}\n\treturn &s, nil\n}\n\n// readSettingsModels returns the enabledModels from settings.json as ModelOptions.\nfunc readSettingsModels() ([]core.ModelOption, error) {\n\ts, err := readSettings()\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/pi/pi.go#L411-L447","documentation":"readSettings resolves pi's settings.json path via settingsPath(), which joins pi's settings dir (derived from HOME / PI_USER_DIR) with settings.json. If the settings directory cannot be determined (empty path), the adapter returns this error instead of attempting a read. It is thrown by readSettings, which backs readSettingsModels and readDefaultModel.","triggerScenarios":"Calling any API that reads pi settings (model listing, default model lookup) when piSettingsDir() returns \"\" — typically when the HOME environment variable is unset/empty and PI_USER_DIR is not set, so the adapter cannot compute ~/.pi/agent.","commonSituations":"Running the daemon under systemd/launchd/docker with a scrubbed environment (no HOME); running as a system service user without a home directory; CI containers that don't set HOME for the service account.","solutions":["Set the HOME environment variable for the process running cc-connect to the user's home directory.","Point the adapter at pi's data explicitly via PI_USER_DIR if supported, so the settings dir is not derived from HOME.","If running under systemd, add Environment=HOME=/home/<user> (or EnvironmentFile) to the unit; under docker pass -e HOME=...","Create ~/.pi/agent/settings.json if pi was never run, though path resolution failing is an env problem, not a missing-file problem."],"exampleFix":"// systemd unit, before\n[Service]\nExecStart=/usr/local/bin/cc-connect\n// after\n[Service]\nEnvironment=HOME=/home/alice\nExecStart=/usr/local/bin/cc-connect","handlingStrategy":"validation","validationCode":"if os.Getenv(\"HOME\") == \"\" && os.Getenv(\"PI_USER_DIR\") == \"\" {\n    return fmt.Errorf(\"cannot read pi settings: HOME/PI_USER_DIR unset in this environment\")\n}\n// proceed with readSettingsModels()/readDefaultModel()","typeGuard":null,"tryCatchPattern":"models, err := readSettingsModels()\nif err != nil && strings.Contains(err.Error(), \"cannot determine settings path\") {\n    return fmt.Errorf(\"pi settings unavailable: set HOME or PI_USER_DIR for the service user: %w\", err)\n}","preventionTips":["Always set HOME explicitly in systemd/docker/launchd service definitions.","Smoke-test the daemon env with `cc-connect doctor` or by printing HOME at startup.","Never assume a daemon inherits your interactive shell environment."],"tags":["go","environment","settings","home-dir"],"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-14T05:17:10.506Z"}