Hmbown/CodeWhale · error
Codewhale issue-report storage owner is not the current user
Error message
Codewhale issue-report storage owner is not the current user
What it means
`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.
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.
Example fix
// before # storage created by elevated run, owned by Administrators # after (run in elevated cmd) takeown /f "%LOCALAPPDATA%\codewhale\issue-reports" /r icacls "%LOCALAPPDATA%\codewhale\issue-reports" /setowner %USERNAME% /t
Defensive patterns
Strategy: validation
Validate before calling
# PowerShell pre-check of storage owner before invoking the tool
$p = "$env:LOCALAPPDATA\codewhale\issue-reports"
if (Test-Path $p) {
$acl = Get-Acl $p
if ($acl.Owner -ne "$env:USERDOMAIN\$env:USERNAME") {
Write-Error "storage owned by $($acl.Owner); run: takeown /f $p /r"
}
} Type guard
fn storage_owner_is_current_user(path: &std::path::Path) -> bool {
// on Windows, compare descriptor owner SID to the process user SID;
// simplest portable proxy: metadata-based ownership check via icacls
std::process::Command::new("icacls")
.arg(path)
.output()
.map(|o| String::from_utf8_lossy(&o.stdout).contains(&whoami::username()))
.unwrap_or(false)
} Try / catch
match report_tool.verify_and_open() {
Ok(handle) => handle,
Err(e) if e.to_string().contains("owner is not the current user") => {
// storage owned by another account: recreate it as this user
std::fs::remove_dir_all(storage_path)?;
report_tool.verify_and_open()
}
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- Codewhale-owned credential file owner is not the current…
- Codewhale-owned xAI OAuth storage owner is not the current…
- Automation lock must not be a reparse point
- Codewhale credentials directory must be owned by the…
- Codewhale issue-report DACL is not current-user-only
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/422d162c3b1226f1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/github/report.rs:1073
// SAFETY: the handle remains valid and all output pointers are writable.
let result = unsafe {
GetSecurityInfo(
file.as_raw_handle(),
SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
&mut owner,
std::ptr::null_mut(),
&mut dacl,
std::ptr::null_mut(),
&mut descriptor,
)
};
if result != ERROR_SUCCESS {
return Err(std::io::Error::from_raw_os_error(result as i32))
.context("reading Codewhale issue-report security descriptor");
}
let _descriptor = WindowsLocalAllocation(descriptor.cast());
anyhow::ensure!(
!owner.is_null() && unsafe { EqualSid(owner, user.sid()) } != 0,
"Codewhale issue-report storage owner is not the current user"
);
anyhow::ensure!(
!dacl.is_null(),
"Codewhale issue-report storage must have an owner-only DACL"
);
let mut count = 0;
let mut entries: *mut EXPLICIT_ACCESS_W = std::ptr::null_mut();
// SAFETY: `dacl` belongs to the live descriptor; Windows allocates the
// returned entry array, released by the guard below.
let result = unsafe { GetExplicitEntriesFromAclW(dacl, &mut count, &mut entries) };
if result != ERROR_SUCCESS {
return Err(std::io::Error::from_raw_os_error(result as i32))
.context("reading Codewhale issue-report DACL entries");
}
let _entries = WindowsLocalAllocation(entries.cast());
anyhow::ensure!(View on GitHub (pinned to 73e0f67d83)