ComposioHQ/composio · critical · KeyringError
PlatformFailure
PlatformFailure
Error message
dlopen(${path}) failed What it means
The macOS keyring FFI layer called dlopen on a system library path and got a NULL handle, meaning the dynamic library could not be loaded. KeyringError kind 'PlatformFailure' with cause 'dlopen(<path>) failed'.
Source
Thrown at ts/packages/cli-keyring/src/stores/macos-security-ffi.ts:86
// Low-level dlopen / dlsym (used to resolve `kSec*` / `kCF*` extern const
// data symbols that `bun:ffi`'s normal dlopen surface doesn't expose).
// -----------------------------------------------------------------------------
const LIBSYSTEM = '/usr/lib/libSystem.B.dylib';
const SECURITY_FRAMEWORK = '/System/Library/Frameworks/Security.framework/Security';
const CORE_FOUNDATION = '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation';
const RTLD_NOW = 0x2;
const libSystem = dlopen(LIBSYSTEM, {
dlopen: { args: [FFIType.ptr, FFIType.i32], returns: FFIType.u64 },
dlsym: { args: [FFIType.u64, FFIType.ptr], returns: FFIType.u64 },
});
function dlopenRaw(path: string): bigint {
const handle = libSystem.symbols.dlopen(cstr(path), RTLD_NOW);
if (handle === 0n) {
throw new KeyringError({
kind: 'PlatformFailure',
cause: new Error(`dlopen(${path}) failed`),
});
}
return handle;
}
/**
* Resolve an extern const CFTypeRef data symbol: `dlsym` returns the
* address of the storage slot (i.e. a pointer-to-pointer); we
* dereference one level via `read.ptr` to get the actual CFTypeRef
* value stored there. The symbol is stable for the process lifetime,
* so caching the resolved BigInt is safe.
*/
function dlsymCFConstant(handle: bigint, name: string): bigint {
const addr = libSystem.symbols.dlsym(handle, cstr(name));
if (addr === 0n) {
throw new KeyringError({View on GitHub (pinned to 64b1b85502)
Solutions
- Verify you are on macOS and the library path exists
- Disable library validation restrictions or run outside the restricting sandbox
- Use a platform-appropriate store for your OS
Defensive patterns
Strategy: validation
Validate before calling
import { platform } from 'node:process';
if (platform !== 'darwin') throw new Error('macOS-only store'); Type guard
const isDarwin = (): boolean => process.platform === 'darwin';
Try / catch
catch (e) { if (e instanceof KeyringError && e.kind === 'PlatformFailure') { /* fall back to file store */ } else throw e; } Prevention
- Select the keyring store by platform at startup
- Avoid sandbox profiles that block dlopen of system libs
When it happens
Trigger: Loading libSystem/CoreFoundation via FFI on a system where the path is wrong, the library is blocked (sandbox/hardened runtime), or running on a non-macOS platform.
Common situations: Sandboxed processes, changed library paths after macOS updates, or accidentally executing the macOS store on Linux/Windows.
Related errors
- dlsym(${name}) failed
- CFStringCreateWithBytes returned NULL
- CFDataGetBytePtr returned NULL
- CFDictionaryCreateMutable returned NULL
- Invalid
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/41236b8fc78df0e1.
Report an issue: GitHub.