Hmbown/CodeWhale · error

Codewhale issue-report DACL must grant only one user

Error message

Codewhale issue-report DACL must grant only one user

What it means

verify_windows_owner_only_handle validates that the DACL of a Codewhale issue-report handle grants exactly one access entry. GetExplicitEntriesFromAclW returned a count other than 1 (or a null entry pointer), so the security descriptor cannot be proven owner-only and the tool refuses to use the handle.

Solutions

  1. Delete the issue-report file/handle and let Codewhale recreate it with its owner-only DACL
  2. Remove extra ACEs so exactly one grant remains, e.g. `icacls <path> /inheritance:r /grant:r "$env:USERNAME:F"`
  3. Verify no group policy or antivirus is re-adding inherited ACEs on the parent directory
  4. Check the handle-creation code path in report.rs for the security descriptor construction

Example fix

// before
icacls report.txt /grant Users:F /grant Administrators:F
// after
icacls report.txt /inheritance:r /grant:r "%USERNAME%":F
Defensive patterns

Strategy: validation

Validate before calling

// PowerShell: confirm the DACL grants exactly one ACE before handing the path to the tool
(Get-Acl $path).Access.Count -eq 1

Try / catch

match verify result { Err(e) if e.to_string().contains("only one user") => recreate_handle(), ... }

Prevention

When it happens

Trigger: The issue-report file/pipe handle was created with a DACL modified by another process, an ACL editor, or a CreateFile with security attributes that added extra ACEs (e.g. inherited group or Everyone entries). Also thrown if GetExplicitEntriesFromAclW succeeded but returned zero entries.

Common situations: Files created under directories whose inherited ACLs add ACEs; security-hardening tools or GPOs rewriting ACLs; manually running icacls edits on the report path; running the report tool against a handle created by an older Codewhale version with different security attributes.

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/c86e205e5a97d5df. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/github/report.rs:1091

        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!(
            count == 1 && !entries.is_null(),
            "Codewhale issue-report 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();
        anyhow::ensure!(
            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,
            "Codewhale issue-report DACL is not current-user-only"
        );
        Ok(())
    }

    #[cfg(windows)]

View on GitHub (pinned to 73e0f67d83)