{"record":{"id":"b6fd1f040a77c0f9","repo":"twpayne/chezmoi","slug":"s-parent-directory-not-in-source-state","errorCode":null,"errorMessage":"%s: parent directory not in source state","messagePattern":"(.+?): parent directory not in source state","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/chezmoi/sourcestate.go","lineNumber":496,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tswitch sourceStateDir, ok := node.SourceStateEntry.(*SourceStateDir); {\n\t\t\t\tcase i != len(nodes)-1 && !ok:\n\t\t\t\t\tpanic(fmt.Errorf(\"nodes[%d]: unexpected non-terminal source state entry, got %T\", i, node.SourceStateEntry))\n\t\t\t\tcase ok && sourceStateDir.attr.External:\n\t\t\t\t\ttargetRelPathComponents := targetRelPath.SplitAll()\n\t\t\t\t\texternalDirRelPath := EmptyRelPath.Join(targetRelPathComponents[:i]...)\n\t\t\t\t\texternalDirRelPaths.Add(externalDirRelPath)\n\t\t\t\t\tif options.Errorf != nil {\n\t\t\t\t\t\toptions.Errorf(\"%s: skipping entries in external_ directory\\n\", externalDirRelPath)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue DEST_ABS_PATH\n\t\t\t\t}\n\t\t\t}\n\t\t\tparentSourceRelPath = nodes[len(nodes)-1].SourceStateEntry.SourceRelPath()\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"%s: parent directory not in source state\", destAbsPath)\n\t\t}\n\t\tnonEmptyDirs.Add(parentSourceRelPath)\n\n\t\tdestAbsPathInfo := destAbsPathInfos[destAbsPath]\n\t\tvar actualStateEntry ActualStateEntry\n\t\tvar newSourceStateEntry SourceStateEntry\n\t\tif destAbsPathInfo == nil {\n\t\t\t// If the destination does not exist then create a new, empty file.\n\t\t\t_, relPath := destAbsPath.Split()\n\t\t\tactualStateEntry = &ActualStateAbsent{\n\t\t\t\tabsPath: destAbsPath,\n\t\t\t}\n\t\t\tfileAttr := FileAttr{\n\t\t\t\tTargetName: relPath.String(),\n\t\t\t\tType:       SourceFileTypeFile,\n\t\t\t\tEncrypted:  options.Encrypt,\n\t\t\t\tEmpty:      true,\n\t\t\t\tTemplate:   options.Template,","sourceCodeStart":478,"sourceCodeEnd":514,"githubUrl":"https://github.com/twpayne/chezmoi/blob/f901167e4685db90da56d6a2a19df642cb3e0247/internal/chezmoi/sourcestate.go#L478-L514","documentation":"During 'chezmoi add', after computing the parent of each target in the source state tree, chezmoi requires that the parent directory of the target already exists as a SourceStateEntry (i.e. is tracked or implicitly present in the source state). If the walk ends without finding the parent directory entry, it cannot determine where to place the new source file, so it fails.","triggerScenarios":"Adding a file whose parent directory cannot be resolved in the source state tree, e.g. adding a deeply nested path when an intermediate directory entry is missing from the source state build (nodes list exhausted without a SourceStateEntry carrying SourceRelPath).","commonSituations":"Adding a path whose parent is ignored via .chezmoiignore; adding files into directories that exist on disk but are excluded from the source state; inconsistent source state after manual edits to the source directory.","solutions":["Check .chezmoiignore (in the source directory) for patterns excluding the target's parent directory and remove/adjust them.","Add the parent directory first (touch a file inside it via 'chezmoi add' of a sibling tracked file) so a directory entry exists.","Verify the source directory structure with 'chezmoi managed' and re-add from a clean state if the source tree was manually edited."],"exampleFix":"// before: dot_config/chezmoi in .chezmoiignore, then\n$ chezmoi add ~/.config/chezmoi/extra.conf\n// after: remove 'dot_config/chezmoi' from .chezmoiignore, then re-run chezmoi add","handlingStrategy":"validation","validationCode":"parent=$(dirname \"${1#$HOME/}\")\nif chezmoi managed | grep -q \"^$parent$\"; then\n  chezmoi add \"$1\"\nelse\n  echo \"parent $parent not managed/ignored? check .chezmoiignore\" >&2\nfi","typeGuard":null,"tryCatchPattern":"// Go caller\nif err := sourceState.Update(...); err != nil {\n  if strings.Contains(err.Error(), \"parent directory not in source state\") {\n    // add parent dir entry or fix .chezmoiignore, then retry\n  }\n}","preventionTips":["Keep .chezmoiignore aligned with what you add","Track parent directories before nested files","Avoid manual edits that desync the source tree"],"tags":["chezmoi","source-state","directory-structure"],"backgroundTag":"missing-path-parent","analyzedSha":"f901167e4685db90da56d6a2a19df642cb3e0247","analyzedAt":"2026-09-01T18:16:41.508Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}