ComposioHQ/composio · error · KeyringError

CFStringCreateWithBytes returned NULL

Error message

CFStringCreateWithBytes returned NULL

What it means

CFStringCreateWithBytes returned NULL when converting a JS string to a CFString for a Security framework query. KeyringError kind 'PlatformFailure'.

Source

Thrown at ts/packages/cli-keyring/src/stores/macos-security-ffi.ts:344

    for (let i = this.refs.length - 1; i >= 0; i--) {
      cf.symbols.CFRelease(this.refs[i]!);
    }
    this.refs.length = 0;
  }
}

/** Create a CFString from a JS string (UTF-8 bytes). Throws on allocation failure. */
function cfStringFromJs(pool: CFPool, s: string): bigint {
  const bytes = textEncoder.encode(s);
  const ref = cf.symbols.CFStringCreateWithBytes(
    0n, // kCFAllocatorDefault
    bytes,
    BigInt(bytes.byteLength),
    kCFStringEncodingUTF8,
    false
  );
  if (ref === 0n) {
    throw new KeyringError({
      kind: 'PlatformFailure',
      cause: new Error('CFStringCreateWithBytes returned NULL'),
    });
  }
  return pool.retain(ref);
}

/** Read a CFString into a JS UTF-8 string. Only used for error messages. */
function cfStringToJs(cfString: bigint): string {
  const buf = new Uint8Array(4096);
  const ok = cf.symbols.CFStringGetCString(
    cfString,
    buf,
    BigInt(buf.byteLength),
    kCFStringEncodingUTF8
  );
  if (!ok) return '<unrepresentable>';
  const end = buf.indexOf(0);

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Retry the operation (transient allocation failures can succeed on retry)
  2. Reduce memory pressure / check for leaks in long-running processes
  3. Update the FFI layer if reproducible and report upstream
Defensive patterns

Strategy: retry

Try / catch

catch (e) { if (e instanceof KeyringError && e.kind === 'PlatformFailure' && /CFStringCreateWithBytes/.test(String(e.cause))) { await sleep(100); return retry(fn, 2); } throw e; }

Prevention

When it happens

Trigger: Calling getSecret/deleteCredential (which build attribute dictionaries) when CoreFoundation cannot allocate the string — invalid encoding input or memory pressure.

Common situations: Extreme memory pressure, or malformed byte input to the FFI layer; rare platform-level allocation failures.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/83fc207ca44133f7. Report an issue: GitHub.