{"record":{"id":"f420f85511a9cf2f","repo":"can1357/oh-my-pi","slug":"failed-to-load-libc-for-linux-child-supervision","errorCode":null,"errorMessage":"failed to load libc for Linux child supervision","messagePattern":"failed to load libc for Linux child supervision","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/utils/src/ptree.ts","lineNumber":47,"sourceCode":"import { dlopen, FFIType } from \"bun:ffi\";\n\nlet libc;\nfor (const soname of ${JSON.stringify(libcCandidates)}) {\n\ttry {\n\t\tlibc = dlopen(soname, {\n\t\t\tprctl: {\n\t\t\t\targs: [FFIType.i32, FFIType.u64, FFIType.u64, FFIType.u64, FFIType.u64],\n\t\t\t\treturns: FFIType.i32,\n\t\t\t},\n\t\t\twaitpid: {\n\t\t\t\targs: [FFIType.i32, FFIType.ptr, FFIType.i32],\n\t\t\t\treturns: FFIType.i32,\n\t\t\t},\n\t\t});\n\t\tbreak;\n\t} catch {}\n}\nif (!libc) throw new Error(\"failed to load libc for Linux child supervision\");\n\nif (libc.symbols.prctl(36, 1, 0, 0, 0) !== 0) {\n\tthrow new Error(\"failed to become a Linux child subreaper\");\n}\n\nconst commandJson = Bun.env.${LINUX_SUBREAPER_COMMAND_ENV};\nif (!commandJson) throw new Error(\"missing supervised command\");\nconst callerBunBeBun = Bun.env.${LINUX_SUBREAPER_BUN_BE_BUN_ENV};\ndelete Bun.env.${LINUX_SUBREAPER_COMMAND_ENV};\ndelete Bun.env.${LINUX_SUBREAPER_BUN_BE_BUN_ENV};\nif (callerBunBeBun === undefined) delete Bun.env.BUN_BE_BUN;\nelse Bun.env.BUN_BE_BUN = callerBunBeBun;\nconst command = JSON.parse(commandJson);\nconst child = Bun.spawn(command, {\n\tstdin: \"inherit\",\n\tstdout: \"pipe\",\n\tstderr: \"pipe\",\n\twindowsHide: true,","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ptree.ts#L29-L65","documentation":"When supervising a child process tree on Linux, ptree spawns a small Bun worker script that dlopens libc via bun:ffi to call prctl(PR_SET_CHILD_SUBREAPER). It tries the candidate sonames (libc.so.6, then libc.so) and throws this error only if every candidate fails to load. It means the FFI bridge to libc could not be established, so child reaping cannot work.","triggerScenarios":"Running a Linux supervised spawn (Bun.spawn with subreaper supervision) on a system where neither 'libc.so.6' nor 'libc.so' can be dlopen'd by Bun — e.g. musl-based distros (Alpine) without glibc compat, minimal containers missing the loader cache, or a stripped runtime without bun:ffi support.","commonSituations":"Alpine/musl Docker images, distroless containers, NixOS with unusual library paths, or cross-distro binaries where glibc sonames are absent.","solutions":["Install glibc (libc6 / glibc package) so libc.so.6 exists and ldconfig cache is populated.","On musl systems, install gcompat or a libc.musl shim and add a libc.so symlink pointing at it.","Verify manually: `bun -e 'require(\"bun:ffi\").dlopen(\"libc.so.6\",{})'` and fix whatever it reports.","Run on a glibc-based base image (e.g. debian:bookworm-slim instead of alpine)."],"exampleFix":"// Dockerfile before (Alpine, no glibc)\nFROM node:alpine\n// after\nFROM node:bookworm  # or: apk add gcompat","handlingStrategy":"fallback","validationCode":"import { dlopen } from 'bun:ffi';\nfor (const soname of ['libc.so.6', 'libc.so']) {\n  try { dlopen(soname, {}); break; } catch {}\n  throw new Error(`libc not loadable: ${soname}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runSupervised(cmd);\n} catch (err) {\n  if (String(err.message).includes('failed to load libc')) {\n    // fall back to direct spawn without subreaper supervision\n    await Bun.spawn(cmd).exited;\n  } else throw err;\n}","preventionTips":["Use glibc-based base images for anything that supervises child processes.","Smoke-test dlopen('libc.so.6') in container startup checks.","On musl, install gcompat and verify the libc.so symlink exists."],"tags":["linux","ffi","libc","subprocess"],"backgroundTag":"libc-dlopen-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}