BoundaryML/baml · error

ErrLoadLibrary

ErrLoadLibrary

Error message

dlopen error for %s: %s

What it means

loadLibrary in lib_unix.go calls C.dlopen to load the BAML native shared library; when dlopen returns nil the raw dlerror() string is wrapped with the library path and tagged code=ErrLoadLibrary. It is the base error for all dynamic-library loading failures on unix/macOS.

Source

Thrown at engine/language_client_go/baml_go/lib_unix.go:30

#include <string.h>
#include <stdint.h>
*/
import "C"
import (
	"fmt"
	"strings"
	"unsafe"
)

// loadLibrary loads the shared library using dlopen
func loadLibrary(path string) (unsafe.Pointer, error) {
	cPath := C.CString(path)
	defer C.free(unsafe.Pointer(cPath))

	handle := C.dlopen(cPath, C.RTLD_LAZY|C.RTLD_LOCAL)
	if handle == nil {
		dlErrStr := C.GoString(C.dlerror())
		dlopenErr := fmt.Errorf("dlopen error for %s: %s", path, dlErrStr)
		if strings.Contains(dlErrStr, "mach-o, but wrong architecture") || strings.Contains(dlErrStr, "wrong ELF class") {
			dlopenErr = fmt.Errorf("%w (architecture mismatch)", dlopenErr)
		} else if strings.Contains(dlErrStr, "cannot open shared object file") {
			if strings.Contains(dlErrStr, "Permission denied") {
				dlopenErr = fmt.Errorf("%w (permission denied)", dlopenErr)
			} else {
				dlopenErr = fmt.Errorf("%w (file not found or inaccessible)", dlopenErr)
			}
		} else if strings.Contains(dlErrStr, "image not found") || strings.Contains(dlErrStr, "no such file or directory") {
			dlopenErr = fmt.Errorf("%w (library or dependency not found)", dlopenErr)
		}
		return nil, dlopenErr
	}
	return handle, nil
}

// getSymbol retrieves a symbol from the loaded library
func getSymbol(handle unsafe.Pointer, name string) (unsafe.Pointer, error) {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Verify the library file exists at `path` and is a valid shared object for the current OS (`file <path>`)
  2. Re-download/reinstall the BAML native library to repair a corrupt artifact
  3. Check dependent shared libraries (`ldd <path>` / `otool -L <path>`) and install missing ones
  4. Confirm the artifact matches your OS/arch (amd64 vs arm64)
  5. Inspect the wrapped dlerror() detail string for the precise OS-level cause

Example fix

// before
handle := C.dlopen(cPath, C.RTLD_LAZY|C.RTLD_LOCAL) // nil, dlerror: wrong ELF class
// after (fix mismatch)
// file baml_cls_abi.so -> ELF 64-bit LSB x86-64 but running arm64:
// reinstall the arm64 build
export TARGET_ARCH=arm64 && go run ./gen/download.go
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(libPath)
if err != nil || info.IsDir() {
    return fmt.Errorf("native library missing at %s", libPath)
}
out, _ := exec.Command("file", libPath).Output() // check ELF/Mach-O matches OS

Try / catch

handle, err := loadLibrary(path)
if errors.Is(err, ErrLoadLibrary) {
    // inspect wrapped dlerror detail; repair artifact or deps before retry
    return repairAndReload(path)
}

Prevention

When it happens

Trigger: C.dlopen(path, RTLD_LAZY|RTLD_LOCAL) returns nil during loadLibrary — wrong path, missing dependencies, architecture mismatch, or permissions — and none of the more specific suffixes match.

Common situations: Corrupt or partially downloaded .so/.dylib; missing transitive native dependencies; wrong platform artifact shipped; LD_LIBRARY_PATH/DYLD_LIBRARY_PATH misconfigured.

Related errors


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