Skip to content

Don't crash reading the config of a subrepo with no remote tree - #3577

Merged
peterebden merged 1 commit into
thought-machine:masterfrom
jackmarsh:fix/remotefs-nil-tree
Aug 18, 2026
Merged

Don't crash reading the config of a subrepo with no remote tree#3577
peterebden merged 1 commit into
thought-machine:masterfrom
jackmarsh:fix/remotefs-nil-tree

Conversation

@jackmarsh

Copy link
Copy Markdown
Contributor

Building a Rust plugin against a repo with ~100 crate subrepos, we hit an intermittent segfault under remote execution whenever Please read a subrepo's config:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18]
please/src/remote/fs.New({...}, 0x0, {...})     fs.go:67
please/src/remote.(*Client).SubrepoFS(...)      remote.go:330
please/src/core.(*Subrepo).FS.func1()           subrepo.go:58
please/src/core.readSubrepoConfig(...)          subrepo.go:119

Note the literal 0x0 argument. SubrepoFS looks the subrepo's output tree up by label and passes whatever it finds straight to remotefs.New:

tree := c.subrepoTrees[target.Label]
return remotefs.New(c.remoteFSClient, tree, root)

subrepoTrees is only ever populated in one place (utils.go, when a target's outputs are set from a remote build), so a subrepo that was built locally, served from the cache, or not built yet has no entry, and tree is nil. New then does append(tree.Children, tree.Root) and dies. readSubrepoConfig calls Subrepo.FS() unconditionally — it has to, in order to look for .plzconfig — so any repo whose subrepo targets can come from cache rather than a fresh remote build can hit this.

That matches what we saw: it was sensitive to cache state and flipped between otherwise identical runs.

This makes a nil tree (or one with no root) produce an empty filesystem, so the config lookup reports "does not exist" and parsing continues — which is already the handling for a subrepo that has no .plzconfig. The added test panics at the same addr=0x18 without the change and passes with it.

plz test //src/remote/... is green.

Comment thread src/remote/fs/fs.go Outdated
tree = &pb.Tree{}
}
if tree.Root == nil {
tree = &pb.Tree{Root: &pb.Directory{}, Children: tree.Children}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tree = &pb.Tree{Root: &pb.Directory{}, Children: tree.Children}
tree.Root = &pb.Directory{}

Think this is slightly clearer about what it wants to do

SubrepoFS looks a subrepo's output tree up by label and passes whatever it
finds to remotefs.New:

    tree := c.subrepoTrees[target.Label]
    return remotefs.New(c.remoteFSClient, tree, root)

subrepoTrees is populated only when a target's outputs are set from a remote
build, so a subrepo built locally, served from cache, or not yet built has
no entry and tree is nil. New then dereferences it while indexing the tree's
children, segfaulting at addr=0x18 during readSubrepoConfig, which calls
Subrepo.FS() unconditionally to look for .plzconfig.

A nil tree (or one without a root) now yields an empty filesystem, so the
lookup reports that the file does not exist and parsing carries on, which is
already how a subrepo without a .plzconfig is handled.
@jackmarsh
jackmarsh force-pushed the fix/remotefs-nil-tree branch from 110fa9d to df325f8 Compare August 17, 2026 13:06
@jackmarsh

Copy link
Copy Markdown
Contributor Author

Applied, thanks - reads better.

@peterebden peterebden left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@peterebden
peterebden merged commit c7335ae into thought-machine:master Aug 18, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants