{"record":{"id":"f3ac6eba352f25f8","repo":"astrid-runtime/astrid","slug":"context-source","errorCode":null,"errorMessage":"{context}: {source}","messagePattern":"\\{context\\}: \\{source\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-core/src/local_transport/windows/helpers.rs","lineNumber":13,"sourceCode":"//! Small Windows encoding and operating-system error helpers.\n\nuse std::ffi::OsStr;\nuse std::io;\nuse std::os::windows::ffi::OsStrExt as _;\n\npub(super) fn wide_nul(value: &OsStr) -> Vec<u16> {\n    value.encode_wide().chain(std::iter::once(0)).collect()\n}\n\npub(super) fn last_error(context: &str) -> io::Error {\n    let source = io::Error::last_os_error();\n    io::Error::new(source.kind(), format!(\"{context}: {source}\"))\n}\n","sourceCodeStart":1,"sourceCodeEnd":15,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-core/src/local_transport/windows/helpers.rs#L1-L15","documentation":"last_error is the helpers.rs wrapper that converts the last Win32 error (io::Error::last_os_error) into an io::Error whose message is '{context}: {source}'. It is the library's generic OS-call failure path for the Windows local transport (e.g. 'failed to read Windows token user', 'failed to create well-known Windows SID', 'failed to inspect named-pipe security descriptor control'). The original OS error code and kind are preserved, so the text after the colon is the authoritative Win32 failure.","triggerScenarios":"Any failing Win32 API call in the Windows local-transport path that reports via GetLastError — GetTokenInformation, CreateWellKnownSid, GetSecurityDescriptorControl, etc. — before pipe ACL validation even begins.","commonSituations":"Access denied when opening the process token under restricted service accounts; running in stripped-down environments (containers, minimal service sessions) where token/SID APIs fail; handle validity issues; Win32 ERROR_NOT_ENOUGH_MEMORY under resource pressure.","solutions":["Read the {source} part of the message (e.g. 'Access is denied. (os error 5)') and map the Win32 code to the failing operation named in {context}.","For 'Access is denied' on token reads, run the process under an account that can query its own token, or avoid restricted-token/AppContainer contexts.","Retry transient OS failures (out-of-memory, transient handle errors) with backoff.","If a specific context string recurs on a supported platform, report it — the wrapping helper should not normally fail."],"exampleFix":"// before: ignoring the underlying OS code when logging\nlog::error!(\"transport setup failed: {}\", err);\n// after: surface both context and OS error for diagnosis\nlog::error!(\"transport setup failed: {err} (kind={:?})\", err.kind());\n// match err.raw_os_error() { Some(5) => /* access denied path */, ... }","handlingStrategy":"try-catch","validationCode":"// Preflight the operations that commonly fail before connecting:\n// token readability (OpenProcessToken/GetTokenInformation) and CreateWellKnownSid succeed\nlet sid = current_user_sid().map_err(|e| format!(\"environment cannot query token: {e}\"))?;","typeGuard":null,"tryCatchPattern":"match transport::connect(&path) {\n    Err(e) if e.raw_os_error() == Some(5) => eprintln!(\"access denied: {}\", e), // inspect {context}: prefix\n    Err(e) if e.raw_os_error() == Some(8) => eprintln!(\"transient out-of-memory: {}\", e), // retry\n    r => r?,\n}","preventionTips":["Parse the '{context}: {source}' message — context names the failing Win32 call, source carries the os error code","Run services under accounts that can query their own process token","Retry on transient OS errors (memory/handle pressure) with backoff","Log err.raw_os_error() alongside the message for support escalations"],"tags":["windows","os-error","win32","ipc"],"backgroundTag":"api-error-response","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}