BoundaryML/baml · critical

GetProcAddress failed for %s: error code %d: %w

Error message

GetProcAddress failed for %s: error code %d: %w

What it means

getSymbol on Windows reports this error when GetProcAddress returns 0, meaning the requested exported symbol does not exist in the loaded BAML DLL (or the handle is invalid). The message includes the symbol name, the GetLastError code, and the syscall error. This indicates a version mismatch between the Go bindings and the native library, or a broken handle.

Source

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

	return unsafe.Pointer(handle), nil
}

// getSymbol retrieves a symbol from the loaded library
func getSymbol(handle unsafe.Pointer, name string) (unsafe.Pointer, error) {
	namePtr, err := syscall.BytePtrFromString(name)
	if err != nil {
		return nil, fmt.Errorf("invalid symbol name: %w", err)
	}

	proc, _, err := procGetProcAddress.Call(
		uintptr(handle),
		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

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Align versions: update the baml Go module and ensure the bundled native DLL comes from the same release (go mod tidy, clean rebuild).
  2. Search the filesystem and DLL search path for duplicate/stale baml DLLs that may shadow the expected one; delete or reorder.
  3. Verify the symbol exists in the deployed DLL (dumpbin /exports baml.dll) and compare with what the bindings request.
  4. Reinstall the module and native artifacts to rule out a corrupted or partially-extracted DLL.

Example fix

// before
// go.mod pinned to baml v0.x but native lib from v0.y
require github.com/boundaryml/baml v0.80.0

// after
// upgrade module so bindings and DLL are from the same release
go get github.com/boundaryml/baml@latest
go mod tidy
# then delete stale baml*.dll copies from PATH directories
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command("dumpbin", "/exports", dllPath).Output()
if err != nil || !strings.Contains(string(out), symbolName) {
    return fmt.Errorf("symbol %s not exported by %s — version mismatch?", symbolName, dllPath)
}

Type guard

func symbolExported(dllPath, symbol string) bool {
    out, err := exec.Command("dumpbin", "/exports", dllPath).Output()
    return err == nil && strings.Contains(string(out), symbol)
}

Try / catch

proc, err := getSymbol(handle, name)
if err != nil {
    return fmt.Errorf("native library may be outdated for %s: %w — realign baml module and DLL versions", name, err)
}

Prevention

When it happens

Trigger: Looking up a BAML FFI symbol that the loaded DLL does not export — typically because the native .dll is an older/newer build than the Go bindings expect; also when called with a handle that LoadLibrary did not actually return.

Common situations: Mixed versions after a partial upgrade of the baml Go module while a stale DLL remains on disk or in the deployment; building bindings from source against a different native artifact; a cached/old DLL earlier on the DLL search path shadowing the correct one.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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