BigPizzaV3/CodexPlusPlus · error · anyhow::Error
GetPackagesByPackageFamily failed with {}
Error message
GetPackagesByPackageFamily failed with {} What it means
Windows-only MSIX support in app_paths.rs enumerates packages for a package family via GetPackagesByPackageFamily using the two-call sizing pattern. The first call is made with a null buffer and must return ERROR_INSUFFICIENT_BUFFER (APPMODEL_ERROR_NO_PACKAGE or SUCCESS with count 0 are also accepted as 'no packages'). Any other Win32 status on this first call bails with the raw code number.
Source
Thrown at crates/codex-plus-core/src/app_paths.rs:160
.encode_utf16()
.chain(std::iter::once(0))
.collect::<Vec<_>>();
let mut count = 0u32;
let mut buffer_length = 0u32;
let first = unsafe {
GetPackagesByPackageFamily(
PCWSTR(family.as_ptr()),
&mut count,
None,
&mut buffer_length,
PWSTR(std::ptr::null_mut()),
)
};
if first == APPMODEL_ERROR_NO_PACKAGE || (first == ERROR_SUCCESS && count == 0) {
return Ok(Vec::new());
}
if first != ERROR_INSUFFICIENT_BUFFER {
bail!("GetPackagesByPackageFamily failed with {}", first.0);
}
let mut pointers = vec![PWSTR(std::ptr::null_mut()); count as usize];
let mut buffer = vec![0u16; buffer_length as usize];
let status = unsafe {
GetPackagesByPackageFamily(
PCWSTR(family.as_ptr()),
&mut count,
Some(pointers.as_mut_ptr()),
&mut buffer_length,
PWSTR(buffer.as_mut_ptr()),
)
};
if status != ERROR_SUCCESS {
bail!("GetPackagesByPackageFamily failed with {}", status.0);
}
buffer.truncate(buffer_length as usize);
bufferView on GitHub (pinned to fb3ebd9a82)
Solutions
- Look up the numeric code from the message (map it with std::io::Error::from_raw_os_error) and check the family name being passed
- Verify the family name shape Name_PublisherHash via PowerShell: Get-AppxPackage | Select PackageFamilyName
- Confirm the package is registered for the current user with Get-AppxPackage <name>
- If the status looks transient (resources/service), retry the enumeration once after a short delay
Example fix
// before
if first != ERROR_INSUFFICIENT_BUFFER {
bail!("GetPackagesByPackageFamily failed with {}", first.0);
}
// after - include the readable Win32 message for diagnosis
if first != ERROR_INSUFFICIENT_BUFFER {
bail!(
"GetPackagesByPackageFamily failed with {} ({})",
first.0,
std::io::Error::from_raw_os_error(first.0 as i32)
);
} Defensive patterns
Strategy: fallback
Validate before calling
// Validate family-name shape before calling the AppModel API
fn valid_family_name(family: &str) -> bool {
let mut parts = family.splitn(2, '_');
matches!((parts.next(), parts.next()), (Some(n), Some(p)) if !n.is_empty() && !p.is_empty()
&& family.chars().all(|c| c.is_ascii_alphanumeric() || c == '.' || c == '_' || c == '-'))
} Try / catch
let packages = match package_full_names_by_family(&family) {
Ok(names) => names,
Err(error) => {
tracing::warn!("package enumeration failed ({error:#}); falling back to Program Files roots");
windows_app_package_roots().into_iter().map(|root| root.join(app_folder)).collect()
}
}; Prevention
- Derive the family name from the app manifest at build time instead of hardcoding
- Treat APPMODEL_ERROR_NO_PACKAGE as 'running unpackaged' and skip the packaged path
- Map the raw code to std::io::Error when logging so the message is readable
- Test on clean Windows VMs with and without the MSIX installed
When it happens
Trigger: The sizing call returns something other than ERROR_INSUFFICIENT_BUFFER: ERROR_INVALID_PARAMETER for a malformed family name (missing or wrong publisher-hash segment), ERROR_INSUFFICIENT_RESOURCES, or ERROR_SUCCESS with count > 0 (only count == 0 success is accepted).
Common situations: A hardcoded or derived package family name with a typo; running on Windows Server or a stripped image without full AppModel support; corrupted package registration where Get-AppxPackage still lists the app.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@fb3ebd9a82 (2026-08-17).
Data as JSON: /api/errors/ebddf399d632e111.
Report an issue: GitHub.