{"record":{"id":"ef8cfe83ac160f6d","repo":"BoundaryML/baml","slug":"freelibrary-failed-w","errorCode":null,"errorMessage":"FreeLibrary failed: %w","messagePattern":"FreeLibrary failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/baml_go/lib_windows.go","lineNumber":72,"sourceCode":"\t\tuintptr(unsafe.Pointer(namePtr)),\n\t)\n\n\tif proc == 0 {\n\t\tlastErr, _, _ := procGetLastError.Call()\n\t\treturn nil, fmt.Errorf(\"GetProcAddress failed for %s: error code %d: %w\", name, lastErr, err)\n\t}\n\n\treturn unsafe.Pointer(proc), nil\n}\n\n// closeLibrary closes the loaded library\nfunc closeLibrary(handle unsafe.Pointer) error {\n\tif handle == nil {\n\t\treturn nil\n\t}\n\tret, _, err := procFreeLibrary.Call(uintptr(handle))\n\tif ret == 0 {\n\t\treturn fmt.Errorf(\"FreeLibrary failed: %w\", err)\n\t}\n\treturn nil\n}\n\n// platformInit performs any platform-specific initialization\nfunc platformInit() error {\n\t// Windows doesn't need special initialization\n\treturn nil\n}","sourceCodeStart":54,"sourceCodeEnd":81,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/baml_go/lib_windows.go#L54-L81","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Ensure single ownership of the library handle: free it exactly once (sync.Once) and nil the reference after freeing.","Wait for all goroutines using the BAML runtime to finish before closing the library.","Inspect the wrapped syscall error for the underlying Win32 code and address it (e.g. handle validity).","If unloading is not required, skip closeLibrary and let process exit release the DLL."],"exampleFix":"// before\nfunc shutdown() {\n    closeLibrary(handle)\n}\n// shutdown() called from two places -> FreeLibrary failed\n\n// after\nvar freeOnce sync.Once\nfunc shutdown() {\n    freeOnce.Do(func() {\n        if err := closeLibrary(handle); err != nil {\n            log.Printf(\"FreeLibrary warning: %v\", err)\n        }\n        handle = nil\n    })\n}","handlingStrategy":"try-catch","validationCode":"if handle == nil || freed {\n    return nil\n}","typeGuard":"func freeable(h unsafe.Pointer, freed bool) bool {\n    return h != nil && !freed\n}","tryCatchPattern":"if err := closeLibrary(handle); err != nil {\n    log.Printf(\"FreeLibrary warning (DLL released at process exit): %v\", err)\n}","preventionTips":["Free the DLL exactly once via sync.Once; nil the handle afterwards.","Join all goroutines using the runtime before unloading.","Skip explicit unload if the process is about to exit."],"tags":["windows","dynamic-linking","dll","resource-cleanup"],"backgroundTag":"dlclose-failed","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}