Hmbown/CodeWhale · error

Codewhale-owned xAI OAuth storage owner is not the current…

Error message

Codewhale-owned xAI OAuth storage owner is not the current user

What it means

verify_windows_owner_only_handle reads the security descriptor of the opened credentials object (file or directory) and requires the owner SID to equal the current user's SID, plus an owner-only DACL. If the owner is another account (e.g. after an admin created the file, or a profile copy changed ownership), the owner-only confidentiality guarantee fails and the error is raised.

Solutions

  1. Run Codewhale as the same user that owns the files (don't mix elevated and normal invocations): check with `icacls <path>`
  2. Take ownership back: `icacls <path> /setowner %USERNAME%` (or `takeown /F <path> /R`), then retry
  3. Delete the credential file/directory and log in again as the current user so fresh owner-correct objects are created

Example fix

// before: file owned by Administrator, run as me
// icacls auth.json  ->  Owner: BUILTIN\Administrators
// after
takeown /F C:\Users\me\.codewhale\xai /R
icacls C:\Users\me\.codewhale\xai /setowner %USERNAME%
Defensive patterns

Strategy: try-catch

Validate before calling

// Windows pre-check: current user owns the path?
fn owner_check_ok(p: &std::path::Path) -> bool {
    // compare via icacls output or GetNamedSecurityInfo in a helper
    true
}

Try / catch

match XaiCredentialStore::open(&dir) {
    Err(e) if e.to_string().contains("owner is not the current user") => {
        eprintln!("credential storage owned by another account; deleting and re-authenticating");
        std::fs::remove_dir_all(&dir).ok();
        std::fs::create_dir_all(&dir)?;
        XaiCredentialStore::open(&dir)?
    }
    r => r,
}

Prevention

When it happens

Trigger: Opening the credentials store when the file or directory is owned by a different user — running Codewhale elevated (as Administrator) after the files were created by the normal user (or vice versa), or copying the profile with `xcopy /O` / robocopy preserving foreign ownership.

Common situations: Mixing elevated and non-elevated Codewhale runs; restoring credentials from another user's backup; IT-managed profile migration tools changing file ownership; running under a service account that shares the directory.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/f063fa4d58bb95a8. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/xai_credentials.rs:1502

    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-owned xAI OAuth security descriptor");
    }
    let _descriptor = WindowsLocalAllocation(descriptor.cast());
    // SAFETY: `owner` is non-null; `user.sid()` is owned by `user`.
    anyhow::ensure!(
        !owner.is_null() && unsafe { EqualSid(owner, user.sid()) } != 0,
        "Codewhale-owned xAI OAuth storage owner is not the current user"
    );
    anyhow::ensure!(
        !dacl.is_null(),
        "Codewhale-owned xAI OAuth 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-owned xAI OAuth DACL entries");
    }
    let _entries = WindowsLocalAllocation(entries.cast());
    anyhow::ensure!(

View on GitHub (pinned to 73e0f67d83)