{"record":{"id":"3c6827a14e8ef649","repo":"jesseduffield/lazygit","slug":"nothing-to-stage-the-parent-repo-can-only-stage-a","errorCode":null,"errorMessage":"Nothing to stage: the parent repo can only stage a new submodule commit, not the uncommitted changes inside a submodule. Commit inside the submodule first.","messagePattern":"Nothing to stage: the parent repo can only stage a new submodule commit, not the uncommitted changes inside a submodule\\. Commit inside the submodule first\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"pkg/gui/controllers/files_controller.go","lineNumber":555,"sourceCode":"\t\t\treturn err\n\t\t}\n\t\tshouldStage = !noOp\n\t}\n\n\tif shouldStage {\n\t\tself.c.LogAction(stageAction)\n\n\t\tif err := self.optimisticChange(unstagedNodes, self.optimisticStage); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn stage(unstagedNodes)\n\t}\n\n\t// If there's nothing staged to unstage either, then the only thing we acted\n\t// on was an unstageable submodule and nothing happened, so say why.\n\tif !someNodesHaveStagedChanges(nodes) {\n\t\treturn errors.New(self.c.Tr.NothingToStageForSubmodule)\n\t}\n\n\tself.c.LogAction(unstageAction)\n\n\tif err := self.optimisticChange(nodes, self.optimisticUnstage); err != nil {\n\t\treturn err\n\t}\n\n\treturn unstage(nodes)\n}\n\nfunc (self *FilesController) pressWithLock(selectedNodes []*filetree.FileNode) error {\n\t// When filtering, expand directory nodes to individual visible file paths\n\t// so that only filtered files are staged/unstaged.\n\ttoPaths := func(nodes []*filetree.FileNode) []string {\n\t\tif self.context().IsFiltering() {\n\t\t\tvar paths []string\n\t\t\tfor _, node := range nodes {","sourceCodeStart":537,"sourceCodeEnd":573,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/gui/controllers/files_controller.go#L537-L573","documentation":"Thrown by FilesController.toggleStaged as a terminal fallback: the selection contained only a submodule whose dirtiness is uncommitted content inside the submodule (no new submodule commit), there was nothing unstaged to stage, and nothing staged to unstage. The parent repo can only stage a new submodule pointer commit, so the toggle would be a silent no-op and lazygit explains why instead.","triggerScenarios":"Pressing 'space' on a file node that is a dirty/untracked-content submodule — the parent repo sees no stageable change for it and nothing else in the selection is stageable.","commonSituations":"Users treating a submodule like a normal directory and pressing space expecting its inner modifications to be staged from the parent repo.","solutions":["Enter the submodule (lazygit supports nested repos) and commit inside it first","Then return to the parent repo and stage the updated submodule pointer"],"exampleFix":"# before: dirty submodule, space in parent errors\n# after\ncd path/to/submodule && git add -A && git commit -m 'work'\ncd .. && git add path/to/submodule   # stage new pointer","handlingStrategy":"validation","validationCode":"// Before toggling stage on a selection, detect unstageable submodule-only content:\nif len(unstagedNodes) == 0 && !someNodesHaveStagedChanges(nodes) {\n    return errors.New(\"commit inside the submodule first; the parent repo stages only the new pointer\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Commit inside submodules before staging them in the parent repo","Treat dirty submodules as pointers: only new submodule commits are parent-stageable","Provide a 'enter submodule' shortcut in the error path so users can act on it"],"tags":["git","submodule","staging","nested-repo"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}