BoundaryML/baml · critical · RuntimeError

Failed to start tokio runtime because

Error message

Failed to start tokio runtime because:
{e:?}

What it means

This error is raised by the Ruby FFI layer when the embedded tokio async runtime cannot be built. BAML's Ruby bindings use a current-thread tokio runtime (because libruby panics if called from non-Ruby threads), and any failure constructing that runtime is surfaced as a Ruby RuntimeError with the underlying tokio error attached.

Solutions

  1. Check the {:?}-formatted tokio error in the message for the root cause (e.g. IO driver unavailable).
  2. Ensure you run on a supported platform/architecture with a normal OS environment (sockets, epoll/kqueue available).
  3. Upgrade the baml gem / ruby_ffi native extension to the latest version.
  4. Report the issue to BAML if it reproduces on a supported platform — this usually indicates an environment or build problem.
Defensive patterns

Strategy: try-catch

Validate before calling

raise 'unsupported platform' unless RUBY_PLATFORM =~ /linux|darwin/

Try / catch

begin
  runtime = Baml::Runtime.from_directory(dir, ENV.to_h)
rescue RuntimeError => e
  raise unless e.message.include?('Failed to start tokio runtime')
  warn "BAML async runtime failed to init: #{e.message}" ; raise
end

Prevention

When it happens

Trigger: Calling any BAML Ruby API that lazily creates the runtime (e.g. Baml::Runtime.from_directory/from_files or the first call_function) when tokio's runtime Builder.build() fails — typically due to unsupported IO/driver features on the platform or resource exhaustion.

Common situations: Running on an exotic or unsupported platform where tokio drivers cannot initialize; constrained/embedded environments lacking resources; incompatible tokio features enabled at build time.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/fd16f2dd1561c0cb. Report an issue: GitHub.

Appendix: source

Thrown at engine/language_client_ruby/ext/ruby_ffi/src/lib.rs:45

impl Drop for BamlRuntimeFfi {
    fn drop(&mut self) {
        use baml_runtime::runtime_interface::ExperimentalTracingInterface;
        match self.inner.flush() {
            Ok(_) => log::trace!("Flushed BAML log events"),
            Err(e) => log::error!("Error while flushing BAML log events: {e:?}"),
        }
    }
}

impl BamlRuntimeFfi {
    fn make_tokio_runtime(ruby: &Ruby) -> Result<tokio::runtime::Runtime> {
        // NB: libruby will panic if called from a non-Ruby thread, so we stick to the current thread
        // to avoid causing issues
        tokio::runtime::Builder::new_current_thread()
            .enable_all()
            .build()
            .map_err(|e| {
                Error::new(
                    ruby.exception_runtime_error(),
                    format!("Failed to start tokio runtime because:\n{e:?}"),
                )
            })
    }

    pub fn from_directory(
        ruby: &Ruby,
        directory: PathBuf,
        env_vars: HashMap<String, String>,
    ) -> Result<BamlRuntimeFfi> {
        let baml_runtime =
            match BamlRuntime::from_directory(&directory, env_vars, FeatureFlags::new()) {
                Ok(br) => br,
                Err(e) => {
                    return Err(Error::new(
                        ruby.exception_runtime_error(),
                        format!("{:?}", e.context("Failed to initialize BAML runtime")),

View on GitHub (pinned to bd85ce9dee)