sxyazi/yazi · error
Cannot take a null pointer
Error message
Cannot take a null pointer
What it means
CFDict::take (yazi-ffi/src/cf_dict.rs:14) wraps a CoreFoundation CFDictionaryRef. A null CFDictionaryRef is not a valid dictionary (it indicates the caller's lookup, e.g. a Launch Services or plist copy, failed), so `take` refuses to wrap it and bails to prevent later null dereferences.
Source
Thrown at yazi-ffi/src/cf_dict.rs:14
use std::{ffi::{CStr, OsStr, OsString, c_char, c_void}, mem::ManuallyDrop, os::unix::ffi::OsStrExt, path::PathBuf};
use anyhow::{Result, bail};
use core_foundation_sys::{base::{CFRelease, TCFTypeRef}, dictionary::{CFDictionaryGetValueIfPresent, CFDictionaryRef}, string::CFStringRef};
use objc2::{msg_send, runtime::AnyObject};
use super::cf_string::CFString;
pub struct CFDict(CFDictionaryRef);
impl CFDict {
pub fn take(dict: CFDictionaryRef) -> Result<Self> {
if dict.is_null() {
bail!("Cannot take a null pointer");
}
Ok(Self(dict))
}
fn value(&self, key: &str) -> Result<*const c_void> {
let key_ = CFString::new(key)?;
let mut value = std::ptr::null();
if unsafe { CFDictionaryGetValueIfPresent(self.0, key_.as_void_ptr(), &mut value) } == 0
|| value.is_null()
{
bail!("Cannot get the value for the key `{key}`");
}
Ok(value)
}
pub fn bool(&self, key: &str) -> Result<bool> {
let value = self.value(key)?;
#[allow(unexpected_cfgs)]View on GitHub (pinned to 5f901b886b)
Solutions
- Check the underlying CF API's return value/error before calling take; handle the null case as 'metadata not available'.
- Verify the target file/bundle exists and is a valid macOS application or plist source.
- Catch this Result and fall back to defaults instead of propagating, since missing CF metadata is usually non-fatal.
Example fix
// before
let dict = CFDict::take(unsafe { LSCopyApplicationURLsForBundleId(id, null_mut()) })?;
// after
match unsafe { LSCopyApplicationURLsForBundleId(id, null_mut()) } {
p if !p.is_null() => CFDict::take(p)?,
_ => return Ok(Default::default()), // app not installed; no metadata
} Defensive patterns
Strategy: type-guard
Validate before calling
// macOS: check the CF call succeeded before wrapping
let dict_ref = unsafe { CFBundleCopyInfoDictionaryForURL(url) };
if dict_ref.is_null() {
return Ok(Default::default()); // no metadata, not an error
}
let dict = CFDict::take(dict_ref)?; Type guard
fn is_valid_dict(p: CFDictionaryRef) -> bool {
!p.is_null()
} Try / catch
match CFDict::take(raw) {
Ok(dict) => use(dict),
Err(_) => use_defaults(), // null CFDictionaryRef == metadata unavailable
} Prevention
- Always null-check CF returns (they signal failure with NULL, not an error code) before wrapping.
- Verify the bundle/file exists before querying its metadata.
- Treat missing CF metadata as a default-value case, not a hard failure.
When it happens
Trigger: Calling `CFDict::take` with a null `CFDictionaryRef` — typically the result of a failed CF API call such as `CFBundleCopyInfoDictionaryForURL`, `LSCopyApplicationURLsForBundleIdentifier`, or a macOS system API that returns NULL on failure.
Common situations: Reading metadata of a nonexistent or uninstalled macOS application/bundle, a file without an Info.plist, or not checking the null return of the upstream CF function before wrapping it.
Related errors
- Cannot get the value for the key `{key}`
- Allocation failed while creating CFString
- Failed to get the C string from CFString
- Cannot create a disk arbitration session
- Cannot get the IO matching services
AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02).
Data as JSON: /api/errors/8c3ed73a362813ab.
Report an issue: GitHub.