fix: nil pointer panic in getDefaultInstallDir on containerized Linux#2339
Merged
jribbink merged 1 commit intoonflow:masterfrom May 4, 2026
Merged
Conversation
Member
Author
|
I asked https://github.com/qwibitai/nanoclaw to install Flow CLI and it couldn't. The agent opened this PR as root cause of why it couldn't install Flow CLI in it's limited container. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
jribbink
approved these changes
May 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
flowCLI panics immediately on startup with a nil pointer dereference in containerized Linux environments (Docker, CI runners, Kubernetes pods, etc.) where the running UID is not present in/etc/passwd.Root Cause
In
internal/settings/defaults.go,getDefaultInstallDir()callsuser.Current()from Go'sos/userpackage to resolve the home directory:The comment "safe to ignore cache errors" is misleading and incorrect in this context.
user.Current()can fail in two distinct ways:usrmay still be partially populated. Ignoring these might be tolerable./etc/passwd— the process UID has no corresponding entry in the user database. In this caseuser.Current()returnsnil, err. Ignoring the error and then accessingusr.HomeDirdereferences a nil pointer.Because
getDefaultInstallDir()is called during packageinit()(it's used as a map literal value indefaults), the panic fires beforemain()runs. There is no way to recover from it —flow version,flow help, and every other subcommand all crash identically.Why this is common
Containerized environments routinely run processes under UIDs that are not registered in
/etc/passwd:FROM scratchor minimal base images (alpine,distroless) often omit/etc/passwdentries for dynamically assigned UIDsrunAsUser/runAsNonRootsecurity contexts frequently assign arbitrary UIDs/etc/passwdchrootenvironment without a fully populated/etc/passwdReproduction
Fix
Replace
user.Current()withos.UserHomeDir(), which is the idiomatic Go way to resolve the home directory.os.UserHomeDir()uses the following resolution order:user.Current()internally on most platforms$HOMEenvironment variable if the syscall lookup failsThis means it works correctly in all the environments where
user.Current()panics, as long as$HOMEis set (which it almost always is, even in minimal containers). If$HOMEis also absent, it returns an error, which we handle gracefully by returning an empty string — a safe no-op rather than a crash.The fix also removes the
os/userimport (now unused) and applies the same correction to the Windows branch, which has the identical vulnerability.Impact
flowCLI is completely unusable in any containerized Linux environment where the process UID is not in/etc/passwd. Every command panics at startup.flowCLI starts correctly in all environments where$HOMEis set, and fails gracefully (returns an empty default path) in the rare case where neither/etc/passwdnor$HOMEis available.Testing
To verify the fix, build the CLI and run it inside a container with a synthetic UID:
docker run --rm -u 99999 -v $(which flow):/usr/local/bin/flow ubuntu:22.04 flow versionBefore this fix: immediate panic. After: normal output.