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
- Read the wrapped error in the panic message to identify the root cause (platform, download, path, load, or version mismatch).
- If the platform is unsupported, build/run on linux/darwin/windows amd64 or arm64, or pin the app to a supported target.
- 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.
- 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.
- 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
- Pin your build targets (CI matrix, docker --platform) to linux/darwin/windows amd64/arm64 only.
- Pre-download or vendor the correct libbaml_cffi for your exact baml Go version into the image and set BAML_LIBRARY_PATH.
- Never rely on network downloads at container startup in sandboxed/air-gapped environments; set BAML_LIBRARY_DISABLE_DOWNLOAD only when a library is pre-provisioned.
- After upgrading the baml Go module, clear or refresh the library cache so versions match (ErrVersionMismatch otherwise panics the same way).
- Set BAML_LOG=DEBUG during deployment troubleshooting to see which discovery step fails.
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
- internal error: attempted to register unknown function '%s'
- Engine not initialized. Call create_baml_runtime first.
- Project not initialized
- Function panicked: {s}
- ErrLoadLibrary
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b61bb5c7cf4c5bc0.
Report an issue: GitHub.