BoundaryML/baml · critical

panic(initErr)

Error message

panic(initErr)

What it means

The baml_go package runs its library setup inside a package-level init() guarded by sync.Once. If initializeBaml() returns any error (unsupported platform, missing/corrupt shared library, version mismatch, cache-dir failure), init() panics with that error, aborting the whole program. It is thrown because the FFI binding cannot function at all without the native baml_cffi library loaded, and the library treats that as unrecoverable rather than returning errors from every API.

Source

Thrown at engine/language_client_go/baml_go/lib_common.go:110

	initOnce              sync.Once
	bamlLibHandle         unsafe.Pointer
	logger                *slog.Logger
)

func SetSharedLibraryPath(path string) {
	if bamlLibHandle != nil {
		logger.Warn("SetSharedLibraryPath called after BAML library was initialized. Path ignored.", "path", path)
		return
	}
	bamlSharedLibraryPath = path
}

func init() {
	initSlog() // Initialize the logger first
	initOnce.Do(func() {
		initErr = initializeBaml()
		if initErr != nil {
			panic(initErr)
		}
	})
}

func GetInitError() error {
	return initErr
}

func initializeBaml() error {
	if !isSupportedPlatform() {
		err := fmt.Errorf("%w: OS=%s Arch=%s", ErrNotSupportedPlatform, runtime.GOOS, runtime.GOARCH)
		return err
	}

	err := findOrDownloadLibrary()
	if err != nil {
		return fmt.Errorf("%w: %w", ErrInitialization, err)
	}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the wrapped error in the panic message to identify the root cause (platform, download, path, load, or version mismatch).
  2. If the platform is unsupported, build/run on linux/darwin/windows amd64 or arm64, or pin the app to a supported target.
  3. Pre-provision the native library: set BAML_LIBRARY_PATH to a valid libbaml_cffi-<triple>.so/dylib/dll of the matching version, or allow downloads so the cache is populated.
  4. If download is disabled (BAML_LIBRARY_DISABLE_DOWNLOAD=true), either enable it or clear the stale cache dir (or set BAML_CACHE_DIR) so a fresh copy is fetched.
  5. In tests, import the package only when GetInitError()-able platforms are used, or guard with a build tag; the panic occurs at init time so it cannot be caught with recover from user code at call time.

Example fix

// before: app crashes at startup on an offline CI runner
import _ "github.com/boundaryml/baml/engine/language_client_go/baml_go"

// after: provision the library ahead of time in the image/CI step
// RUN curl -L -o /usr/local/lib/libbaml_cffi-x86_64-unknown-linux-gnu.so \
//   https://github.com/boundaryml/baml/releases/download/v0.226.2/libbaml_cffi-x86_64-unknown-linux-gnu.so
// ENV BAML_LIBRARY_PATH=/usr/local/lib/libbaml_cffi-x86_64-unknown-linux-gnu.so
import _ "github.com/boundaryml/baml/engine/language_client_go/baml_go"
Defensive patterns

Strategy: try-catch

Validate before calling

// go env check before building/running
go env GOOS GOARCH  # must be linux|darwin|windows + amd64|arm64
// shell check before starting the binary:
# test -f "${BAML_LIBRARY_PATH:-$HOME/.cache/baml/libs/0.226.2/libbaml_cffi-x86_64-unknown-linux-gnu.so}"

Type guard

if err := baml_go.GetInitError(); err != nil { /* init already panicked; this only helps in builds where init did not run */ }

Try / catch

// The panic happens in package init, before your code runs. Guard at the deployment level:
// in Go you can recover only in a deferred func of main, but init panics abort the process;
// instead, run a preflight subprocess or check env/platform in CI:
func preflight() error {
    if runtime.GOOS != "linux" && runtime.GOOS != "darwin" && runtime.GOOS != "windows" {
        return fmt.Errorf("unsupported GOOS %s", runtime.GOOS)
    }
    if runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64" {
        return fmt.Errorf("unsupported GOARCH %s", runtime.GOARCH)
    }
    return nil
}

Prevention

When it happens

Trigger: Importing package baml_go (any import chain) when initializeBaml() fails: GOOS/GOARCH unsupported, findOrDownloadLibrary() fails (bad BAML_LIBRARY_PATH, BAML_LIBRARY_DISABLE_DOWNLOAD=true with no cached/system library, download network failure), discovered path stat fails, loadLibrary fails, or BamlVersion() != VERSION.

Common situations: Cross-compiling to a platform BAML does not ship (e.g. linux/386, freebsd); running in an air-gapped CI sandbox with downloads disabled and no pre-provisioned library; corrupted or stale cached library in ~/.cache/baml/libs/<version>; BAML_LIBRARY_PATH pointing at a deleted or wrong-arch file; mixing baml Go package version with an older pre-downloaded libbaml.so in /usr/local/lib.

Related errors


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