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

  1. Check the underlying CF API's return value/error before calling take; handle the null case as 'metadata not available'.
  2. Verify the target file/bundle exists and is a valid macOS application or plist source.
  3. 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

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


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/8c3ed73a362813ab. Report an issue: GitHub.