{"record":{"id":"09a1b3b511430a85","repo":"Hmbown/CodeWhale","slug":"codewhale-owned-xai-oauth-path-has-the-wrong-files","errorCode":null,"errorMessage":"Codewhale-owned xAI OAuth path has the wrong filesystem type","messagePattern":"Codewhale-owned xAI OAuth path has the wrong filesystem type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/xai_credentials.rs","lineNumber":1349,"sourceCode":"    use std::os::windows::ffi::OsStringExt as _;\n    use std::os::windows::fs::MetadataExt as _;\n    use std::os::windows::io::AsRawHandle as _;\n    use windows_sys::Win32::Storage::FileSystem::{\n        FILE_ATTRIBUTE_REPARSE_POINT, FILE_NAME_NORMALIZED, GetFinalPathNameByHandleW,\n        VOLUME_NAME_DOS,\n    };\n\n    let metadata = file.metadata().with_context(|| {\n        format!(\n            \"inspecting Codewhale-owned path {}\",\n            crate::quote_os_path(expected)\n        )\n    })?;\n    anyhow::ensure!(\n        metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT == 0,\n        \"Codewhale-owned xAI OAuth path must not be a reparse point\"\n    );\n    anyhow::ensure!(\n        if expect_directory {\n            metadata.is_dir()\n        } else {\n            metadata.is_file()\n        },\n        \"Codewhale-owned xAI OAuth path has the wrong filesystem type\"\n    );\n    let flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;\n    let handle = file.as_raw_handle();\n    // SAFETY: null output asks only for the required UTF-16 length.\n    let needed = unsafe { GetFinalPathNameByHandleW(handle, std::ptr::null_mut(), 0, flags) };\n    if needed == 0 {\n        return Err(std::io::Error::last_os_error())\n            .context(\"resolving Codewhale-owned xAI OAuth handle path\");\n    }\n    let mut buffer = vec![0u16; needed as usize + 1];\n    // SAFETY: the buffer is writable and the handle remains valid.\n    let written = unsafe {","sourceCodeStart":1331,"sourceCodeEnd":1367,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/xai_credentials.rs#L1331-L1367","documentation":"validate_windows_handle_path also verifies the opened object has the expected filesystem type: a directory when expect_directory is true, a regular file otherwise. If the handle resolves to the wrong kind of object (e.g. a file where the credentials directory should be, or a directory at the token-file name), the layout contract is broken and the error is raised.","triggerScenarios":"The credentials directory path points at a regular file, or the token-file name inside it is a directory; opening the store when ~/.codewhale/xai was accidentally replaced by a file (or vice versa) by a script or manual mv.","commonSituations":"A cleanup script doing `rm -rf` partially or creating a file named like the directory; extracting an archive over the profile that turned the directory into a file; manually creating a folder named `auth.json`.","solutions":["Check the path with `dir` / `Get-Item` and fix the type: delete the wrongly typed entry and recreate the directory (or re-login to recreate the file)","Recreate the credentials directory: `mkdir %USERPROFILE%\\.codewhale\\xai` then log in again","Correct the path in config so it points at the directory, not a file"],"exampleFix":"// before (auth.json is a directory)\nrmdir C:\\Users\\me\\.codewhale\\xai\\auth.json\n// after: re-login to recreate the token file\n","handlingStrategy":"validation","validationCode":"fn path_type(p: &std::path::Path) -> Result<&'static str, std::io::Error> {\n    let m = std::fs::metadata(p)?;\n    Ok(if m.is_dir() { \"dir\" } else if m.is_file() { \"file\" } else { \"other\" })\n}","typeGuard":null,"tryCatchPattern":"let store = match XaiCredentialStore::open(&dir) {\n    Err(e) if e.to_string().contains(\"wrong filesystem type\") => {\n        std::fs::remove_file(&dir).ok();\n        std::fs::create_dir_all(&dir)?;\n        XaiCredentialStore::open(&dir)?\n    }\n    r => r?,\n};","preventionTips":["Never create files/dirs whose names collide with the store's layout","Recreate the expected directory with create_dir_all before first use","Avoid destructive scripts that `mv` over the credentials path"],"tags":["filesystem","windows","path"],"backgroundTag":"path-is-not-a-regular-file","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}