Hmbown/CodeWhale · error

current Windows user token has no SID

Error message

current Windows user token has no SID

What it means

On Windows, the GitHub tool opens the current user's access token and reads its TOKEN_USER information to derive the user's SID. If the token carries no user SID (User.Sid is null), the handle is closed and this error is thrown, since SID-based owner filtering cannot proceed. The token handle is leaked-free by design on this path.

Solutions

  1. Run the tool under an interactive user account whose token has a normal user SID.
  2. Check whether security policy or sandboxing is stripping token information and adjust it.
  3. If only run on non-Windows platforms, skip this Windows-specific path or feature-detect it.
Defensive patterns

Strategy: fallback

Try / catch

match ReportOwner::open() {
    Ok(owner) => owner,
    Err(e) if e.to_string().contains("no SID") => {
        // fall back to non-SID-based attribution or skip ownership filter
        skip_sid_filter()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running the GitHub report tool on Windows in a context where GetTokenInformation succeeds but returns no SID — e.g. certain service accounts, impersonation contexts, or exotic token configurations.

Common situations: Running under a Windows service or scheduled task with an unusual token; sandboxed/restricted processes; antivirus or policy software stripping token user info.

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


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

Appendix: source

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

                GetTokenInformation(
                    token,
                    TokenUser,
                    token_info.as_mut_ptr().cast(),
                    needed,
                    &mut needed,
                )
            } == 0
            {
                let error = std::io::Error::last_os_error();
                // SAFETY: the token is owned on this error path.
                unsafe { CloseHandle(token) };
                return Err(error).context("reading current Windows user token information");
            }
            let user = unsafe { &*token_info.as_ptr().cast::<TOKEN_USER>() };
            if user.User.Sid.is_null() {
                // SAFETY: the token is owned on this error path.
                unsafe { CloseHandle(token) };
                bail!("current Windows user token has no SID");
            }
            Ok(Self { token, token_info })
        }

        fn sid(&self) -> windows_sys::Win32::Security::PSID {
            use windows_sys::Win32::Security::TOKEN_USER;
            // SAFETY: the aligned token buffer remains owned by `self`.
            unsafe { (*self.token_info.as_ptr().cast::<TOKEN_USER>()).User.Sid }
        }
    }

    #[cfg(windows)]
    impl Drop for CurrentWindowsUser {
        fn drop(&mut self) {
            // SAFETY: `token` is owned by this guard and closed exactly once.
            unsafe { windows_sys::Win32::Foundation::CloseHandle(self.token) };
        }
    }

View on GitHub (pinned to 73e0f67d83)