BoundaryML/baml · error

FreeLibrary failed: %w

Error message

FreeLibrary failed: %w

What it means

closeLibrary on Windows returns this error when FreeLibrary returns 0, meaning Windows could not decrement the DLL's reference count / unload the BAML native library. It wraps the syscall error. As with dlclose failures, this usually means the handle was invalid or already freed rather than a configuration problem.

Source

Thrown at engine/language_client_go/baml_go/lib_windows.go:72

		uintptr(unsafe.Pointer(namePtr)),
	)

	if proc == 0 {
		lastErr, _, _ := procGetLastError.Call()
		return nil, fmt.Errorf("GetProcAddress failed for %s: error code %d: %w", name, lastErr, err)
	}

	return unsafe.Pointer(proc), nil
}

// closeLibrary closes the loaded library
func closeLibrary(handle unsafe.Pointer) error {
	if handle == nil {
		return nil
	}
	ret, _, err := procFreeLibrary.Call(uintptr(handle))
	if ret == 0 {
		return fmt.Errorf("FreeLibrary failed: %w", err)
	}
	return nil
}

// platformInit performs any platform-specific initialization
func platformInit() error {
	// Windows doesn't need special initialization
	return nil
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure single ownership of the library handle: free it exactly once (sync.Once) and nil the reference after freeing.
  2. Wait for all goroutines using the BAML runtime to finish before closing the library.
  3. Inspect the wrapped syscall error for the underlying Win32 code and address it (e.g. handle validity).
  4. If unloading is not required, skip closeLibrary and let process exit release the DLL.

Example fix

// before
func shutdown() {
    closeLibrary(handle)
}
// shutdown() called from two places -> FreeLibrary failed

// after
var freeOnce sync.Once
func shutdown() {
    freeOnce.Do(func() {
        if err := closeLibrary(handle); err != nil {
            log.Printf("FreeLibrary warning: %v", err)
        }
        handle = nil
    })
}
Defensive patterns

Strategy: try-catch

Validate before calling

if handle == nil || freed {
    return nil
}

Type guard

func freeable(h unsafe.Pointer, freed bool) bool {
    return h != nil && !freed
}

Try / catch

if err := closeLibrary(handle); err != nil {
    log.Printf("FreeLibrary warning (DLL released at process exit): %v", err)
}

Prevention

When it happens

Trigger: closeLibrary called with an invalid or already-freed handle; double-close in teardown paths; FreeLibrary failing because the DLL is still in use (loaded modules referencing it, active threads executing its code).

Common situations: Application shutdown hooks calling close twice; goroutines still running BAML calls while the library is being unloaded; handles copied and freed from multiple code paths.

Related errors


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