Hmbown/CodeWhale · error · io::Error
Codewhale-owned credential file DACL is not…
Error message
Codewhale-owned credential file DACL is not current-user-only
What it means
This error means the Windows discretionary access control list (DACL) on a Codewhale-owned credential file grants access beyond the current user, so the file fails the strict owner-only verification. The library throws it when opening the credential file with require_owner_only=true, after enumerating every ACE and failing to find exactly one access-allowed ACE granting FILE_ALL_ACCESS to the current user's SID via TRUSTEE_IS_SID.
Solutions
- Recreate the credential file so Codewhale rewrites it with a current-user-only DACL (delete the file and re-authenticate or re-run the credential setup)
- Remove extra ACEs and ensure a single GRANT/SET_ACCESS ACE gives the current user SID FILE_ALL_ACCESS (icacls <file> /inheritance:r /grant:r "%USERNAME%:F")
- Copy the file to a fresh location so it inherits a default user-only ACL, then point the config at it
Example fix
// before (broad ACL) icacls cred.json /grant Users:F // after icacls cred.json /inheritance:r /grant:r "%USERNAME%:F"
Defensive patterns
Strategy: validation
Validate before calling
// Windows: check the ACL before relying on the file
use std::os::windows::fs::MetadataExt;
let md = std::fs::metadata(path)?; // plus icacls/SDDL parse if you need full certainty
if !md.permissions().readonly() { /* run: icacls <path> to inspect ACEs */ } Try / catch
match std::fs::read(path) {
Ok(data) => use_credential(&data),
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
eprintln!("credential file ACL not user-only; re-run credential setup");
repair_dacl(path);
}
Err(e) => return Err(e.into()),
} Prevention
- Never copy credential files with tools that preserve broad ACLs; recreate them via Codewhale
- Run icacls <file> /inheritance:r /grant:r "%USERNAME%:F" after any manual restore
- Avoid syncing credential directories with backup/DACL-rewriting tools
- Verify ACLs after OS upgrades or profile migration
When it happens
Trigger: Calling read_codewhale_owned_to_string on a credential file whose DACL was modified (extra ACEs added, permissions narrowed, or trustee expressed as a name rather than SID), so no single ACE matches the current-user-only pattern.
Common situations: File permissions edited manually or by a sync/backup tool that rewrote the ACL; the file was copied from another location preserving broader ACLs; an administrator or installer changed the DACL; the file was created by a different security context.
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 DACL must grant only one…
- Codewhale-owned credential file must be singly linked
- Codewhale-owned credential file must have an owner-only DACL
- Codewhale-owned credential file owner is not the current…
- Codewhale-owned xAI OAuth path must not be a reparse point
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ba9f6fe23668db01.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/external_credentials.rs:505
}
let _entries = WindowsLocalAllocation(entries.cast());
if count != 1 || entries.is_null() {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"Codewhale-owned credential file DACL must grant only one user",
));
}
// SAFETY: `count == 1` proves the first returned entry is initialized.
let entry = unsafe { &*entries };
let trustee_sid: PSID = entry.Trustee.ptstrName.cast();
// SAFETY: form and null checked in this expression; sid owned by `user`.
let current_user_only = entry.Trustee.TrusteeForm == TRUSTEE_IS_SID
&& !trustee_sid.is_null()
&& unsafe { EqualSid(trustee_sid, user.sid()) } != 0
&& matches!(entry.grfAccessMode, SET_ACCESS | GRANT_ACCESS)
&& entry.grfAccessPermissions == FILE_ALL_ACCESS;
if !current_user_only {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
"Codewhale-owned credential file DACL is not current-user-only",
));
}
Ok(())
}
#[cfg(windows)]
struct CurrentWindowsUser {
token: windows_sys::Win32::Foundation::HANDLE,
token_info: Vec<usize>,
}
#[cfg(windows)]
impl CurrentWindowsUser {
fn open() -> io::Result<Self> {
use windows_sys::Win32::Foundation::{GetLastError, HANDLE};
use windows_sys::Win32::Security::{View on GitHub (pinned to 73e0f67d83)