{"record":{"id":"d1c02a58e7992440","repo":"atuinsh/atuin","slug":"there-is-always-at-least-one-potential-socket-path","errorCode":null,"errorMessage":"there is always at least one potential socket path","messagePattern":"there is always at least one potential socket path","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin-client/src/settings/daemon.rs","lineNumber":119,"sourceCode":"        if let Some(path) = &self.socket_path {\n            return SocketPath::UserDefined(path);\n        }\n\n        // systemd units typically listen on `%t/atuin.sock`, which is `$XDG_RUNTIME_DIR/atuin.sock`\n        // for user units, so we should default to that path when `systemd_socket` is true.\n        if self.systemd_socket\n            && let Some(path) = ctx.runtime_socket_path()\n        {\n            return SocketPath::Default(path);\n        }\n\n        SocketPath::Default(ctx.default_socket_path().primary)\n    }\n\n    fn existing_socket_path_ctx(&self, ctx: impl SocketCtx) -> Cow<'_, Path> {\n        let mut candidates = self.potential_socket_paths_ctx(ctx);\n        let primary =\n            candidates.next().expect(\"there is always at least one potential socket path\");\n\n        if primary.exists() {\n            return primary;\n        }\n        candidates.find(|path| path.exists()).unwrap_or(primary)\n    }\n\n    fn potential_socket_paths_ctx(\n        &self,\n        ctx: impl SocketCtx,\n    ) -> impl Iterator<Item = Cow<'_, Path>> {\n        let is_user_defined = self.socket_path.is_some();\n        let defaults = (!is_user_defined)\n            .then(|| self.default_socket_paths(ctx))\n            .into_iter()\n            .flatten()\n            .map(Cow::Owned);\n        self.socket_path.as_deref().map(Cow::Borrowed).into_iter().chain(defaults)","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/atuinsh/atuin/blob/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin-client/src/settings/daemon.rs#L101-L137","documentation":"This is an internal invariant assertion in `existing_socket_path_ctx`: after computing the candidate socket paths, the code calls `.expect(\"there is always at least one potential socket path\")` on the first candidate. The invariant is that `potential_socket_paths_ctx` always yields at least one path (the default). If it ever yields an empty iterator, this panics with that message, indicating a bug in the candidate-generation logic rather than a user-facing problem.","triggerScenarios":"Calling `existing_socket_path` (or `existing_socket_path_ctx`) when `potential_socket_paths_ctx` returns an empty iterator — e.g. a refactor or misconfigured SocketCtx that drops the default path from the candidate list.","commonSituations":"Almost never hit in practice; arises from code changes to candidate generation, or from constructing a settings/SocketCtx state where XDG/home directory resolution produces no paths.","solutions":["Inspect `potential_socket_paths_ctx` and ensure the default socket path is always the first candidate","Verify the SocketCtx passed in resolves a non-empty default path (check XDG_RUNTIME_DIR / home dir resolution)","If you control the caller, fall back to `SocketPath::Default(...).into()` instead of asserting"],"exampleFix":"// before\nlet primary = candidates.next().expect(\"there is always at least one potential socket path\");\n// after\nlet Some(primary) = candidates.next() else {\n    return Cow::Owned(ctx.default_socket_path().primary);\n};","handlingStrategy":"type-guard","validationCode":"// caller-side sanity check\nassert!(SocketPath::Default(ctx.default_socket_path().primary).as_path().parent().is_some());","typeGuard":"fn has_candidates(paths: impl Iterator<Item = PathBuf>) -> bool { paths.count() > 0 }","tryCatchPattern":"// expect() panics cannot be caught; verify candidate generation in tests instead\n#[test]\nfn default_ctx_yields_at_least_one_socket_path() { assert!(paths(ctx).next().is_some()); }","preventionTips":["Keep the default socket path as the first candidate in potential_socket_paths_ctx","Add a unit test asserting the iterator is non-empty for all SocketCtx variants","Avoid refactoring candidate generation without re-running socket path tests"],"tags":["panic","invariant","socket-path","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}