{"record":{"id":"f3ca546b51543dad","repo":"BoundaryML/baml","slug":"dlclose-failed-s","errorCode":null,"errorMessage":"dlclose failed: %s","messagePattern":"dlclose failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/baml_go/lib_unix.go","lineNumber":80,"sourceCode":"\t\tif errStr != \"\" {\n\t\t\terrMsg += fmt.Sprintf(\": %s\", errStr)\n\t\t} else {\n\t\t\terrMsg += \": symbol not found\"\n\t\t}\n\t\treturn nil, fmt.Errorf(\"%s\", errMsg)\n\t}\n\treturn symbol, 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\tif C.dlclose(handle) != 0 {\n\t\terrStr := C.GoString(C.dlerror())\n\t\tif errStr != \"\" {\n\t\t\treturn fmt.Errorf(\"dlclose failed: %s\", errStr)\n\t\t}\n\t\treturn fmt.Errorf(\"dlclose failed\")\n\t}\n\treturn nil\n}\n\n// platformInit performs any platform-specific initialization\nfunc platformInit() error {\n\t// Unix doesn't need special initialization\n\treturn nil\n}","sourceCodeStart":62,"sourceCodeEnd":91,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/baml_go/lib_unix.go#L62-L91","documentation":"This error is returned by closeLibrary when the cgo dlclose() call fails to unload the BAML native shared library on Unix platforms. dlclose() returns nonzero when the handle is invalid or the library cannot be unloaded, and the library then surfaces the OS-provided dlerror() string for diagnosis. It almost always indicates a corrupted or invalid library handle rather than a problem with BAML configuration itself.","triggerScenarios":"Calling code that obtained a handle via loadLibrary (dlopen) and then calls closeLibrary with a handle that was already closed, was invalidated, or was corrupted. Also occurs if the dynamic linker refuses to unload the .so due to lingering references or linker state.","commonSituations":"Double-closing the library in cleanup/teardown paths; tests that load and unload the native library multiple times in one process; corrupted native binaries or mismatched library versions shipped with the Go bindings; platforms with unusual dlopen/dlclose semantics (e.g. musl vs glibc).","solutions":["Ensure closeLibrary is called at most once per successful loadLibrary handle; guard cleanup with a sync.Once or nil-out the handle after closing.","Read the %s detail from dlerror() to identify the underlying linker error and act on it (e.g. missing dependency of the .so).","Verify the bundled BAML native library file is intact and matches your baml Go module version (reinstall/refresh the dependency).","If the error appears only in tests, avoid unloading the library between test cases; load once per process."],"exampleFix":"// before\nif err := closeLibrary(handle); err != nil {\n    return err\n}\nhandle = maybeStaleHandle\n\n// after\nvar closeOnce sync.Once\ncloseOnce.Do(func() {\n    if err := closeLibrary(handle); err != nil {\n        log.Printf(\"dlclose warning: %v\", err)\n    }\n    handle = nil\n})","handlingStrategy":"try-catch","validationCode":"if handle != nil && !closed {\n    _ = closeLibrary(handle)\n    closed = true\n}","typeGuard":"func canClose(h unsafe.Pointer, closed bool) bool {\n    return h != nil && !closed\n}","tryCatchPattern":"if err := closeLibrary(handle); err != nil {\n    log.Printf(\"dlclose warning (non-fatal at process exit): %v\", err)\n}","preventionTips":["Close the library handle exactly once per load, using sync.Once.","Nil out the handle after closing so stale reuse is impossible.","Treat unload failures at process exit as non-fatal and log them."],"tags":["cgo","dynamic-linking","unix","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"}