{"record":{"id":"422d162c3b1226f1","repo":"Hmbown/CodeWhale","slug":"codewhale-issue-report-storage-owner-is-not-the-current-user","errorCode":null,"errorMessage":"Codewhale issue-report storage owner is not the current user","messagePattern":"Codewhale issue-report storage owner is not the current user","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/github/report.rs","lineNumber":1073,"sourceCode":"        // SAFETY: the handle remains valid and all output pointers are writable.\n        let result = unsafe {\n            GetSecurityInfo(\n                file.as_raw_handle(),\n                SE_FILE_OBJECT,\n                OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,\n                &mut owner,\n                std::ptr::null_mut(),\n                &mut dacl,\n                std::ptr::null_mut(),\n                &mut descriptor,\n            )\n        };\n        if result != ERROR_SUCCESS {\n            return Err(std::io::Error::from_raw_os_error(result as i32))\n                .context(\"reading Codewhale issue-report security descriptor\");\n        }\n        let _descriptor = WindowsLocalAllocation(descriptor.cast());\n        anyhow::ensure!(\n            !owner.is_null() && unsafe { EqualSid(owner, user.sid()) } != 0,\n            \"Codewhale issue-report storage owner is not the current user\"\n        );\n        anyhow::ensure!(\n            !dacl.is_null(),\n            \"Codewhale issue-report storage must have an owner-only DACL\"\n        );\n        let mut count = 0;\n        let mut entries: *mut EXPLICIT_ACCESS_W = std::ptr::null_mut();\n        // SAFETY: `dacl` belongs to the live descriptor; Windows allocates the\n        // returned entry array, released by the guard below.\n        let result = unsafe { GetExplicitEntriesFromAclW(dacl, &mut count, &mut entries) };\n        if result != ERROR_SUCCESS {\n            return Err(std::io::Error::from_raw_os_error(result as i32))\n                .context(\"reading Codewhale issue-report DACL entries\");\n        }\n        let _entries = WindowsLocalAllocation(entries.cast());\n        anyhow::ensure!(","sourceCodeStart":1055,"sourceCodeEnd":1091,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/github/report.rs#L1055-L1091","documentation":"`verify_windows_owner_only_handle` reads the security descriptor of the Codewhale issue-report storage and `anyhow::ensure!`s that the descriptor's owner SID equals the current user's SID. When the owner is null or a different account owns the storage, it throws this error. This is a hardening check so private issue reports cannot be read or tampered with by another local account.","triggerScenarios":"Calling the issue-report tool on Windows when the storage file/directory's ACL owner is another user — e.g. the storage was first created by an elevated (admin) process, a different service account, or a profile migration changed ownership.","commonSituations":"First run under 'Run as administrator' creates the storage owned by Administrators, then a normal user run hits the mismatch; a backup/restore or robocopy copy rewrote ownership; the user account was recreated with a new SID.","solutions":["Take ownership as the current user: `takeown /f <storage-path> /r` then `icacls <storage-path> /setowner %USERNAME%` (run elevated).","Simplest: delete the issue-report storage directory and let the current (non-elevated) Codewhale recreate it with correct ownership.","Avoid running Codewhale elevated for the first-time creation of the storage; run it as the normal user.","If a domain/profile migration changed the SID, recreate the storage under the new profile."],"exampleFix":"// before\n# storage created by elevated run, owned by Administrators\n# after (run in elevated cmd)\ntakeown /f \"%LOCALAPPDATA%\\codewhale\\issue-reports\" /r\nicacls \"%LOCALAPPDATA%\\codewhale\\issue-reports\" /setowner %USERNAME% /t","handlingStrategy":"validation","validationCode":"# PowerShell pre-check of storage owner before invoking the tool\n$p = \"$env:LOCALAPPDATA\\codewhale\\issue-reports\"\nif (Test-Path $p) {\n  $acl = Get-Acl $p\n  if ($acl.Owner -ne \"$env:USERDOMAIN\\$env:USERNAME\") {\n    Write-Error \"storage owned by $($acl.Owner); run: takeown /f $p /r\"\n  }\n}","typeGuard":"fn storage_owner_is_current_user(path: &std::path::Path) -> bool {\n    // on Windows, compare descriptor owner SID to the process user SID;\n    // simplest portable proxy: metadata-based ownership check via icacls\n    std::process::Command::new(\"icacls\")\n        .arg(path)\n        .output()\n        .map(|o| String::from_utf8_lossy(&o.stdout).contains(&whoami::username()))\n        .unwrap_or(false)\n}","tryCatchPattern":"match report_tool.verify_and_open() {\n    Ok(handle) => handle,\n    Err(e) if e.to_string().contains(\"owner is not the current user\") => {\n        // storage owned by another account: recreate it as this user\n        std::fs::remove_dir_all(storage_path)?;\n        report_tool.verify_and_open()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always run Codewhale for first-time setup as the normal (non-elevated) user on Windows.","Never create the issue-report storage with admin tools or elevated shells.","After profile or domain migration, delete and recreate the storage under the new SID.","Use ACL-preserving copies (robocopy /COPYALL) if the storage must be moved."],"tags":["windows","security","ownership"],"backgroundTag":"insufficient-permissions","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"}