plandex-ai/plandex · error
error checking if %s is a subpath of %s: %s
Error message
error checking if %s is a subpath of %s: %s
What it means
ParseInputPaths checks each user-supplied path to see whether it is a subpath of one of the original fileOrDirPaths using fs.IsSubpathOf. If that filesystem/path check errors, the failure is wrapped with this message identifying both the child path and the parent candidate. It means path normalization failed before any context was loaded.
Source
Thrown at app/cli/lib/context_paths.go:31
LoadParams *types.LoadContextParams
}
func ParseInputPaths(params ParseInputPathsParams) ([]string, error) {
fileOrDirPaths := params.FileOrDirPaths
baseDir := params.BaseDir
projectPaths := params.ProjectPaths
loadParams := params.LoadParams
resPaths := []string{}
for path := range projectPaths.AllPaths {
// see if it's a child of any of the fileOrDirPaths
found := false
for _, p := range fileOrDirPaths {
var err error
found, err = fs.IsSubpathOf(p, path, baseDir)
if err != nil {
return nil, fmt.Errorf("error checking if %s is a subpath of %s: %s", path, p, err)
}
if found {
break
}
}
if !found {
continue
}
if projectPaths.AllDirs[path] {
if !(loadParams.Recursive || loadParams.NamesOnly || loadParams.DefsOnly) {
// log.Println("path", path, "info.Name()", info.Name())
return nil, fmt.Errorf("cannot process directory %s: requires --recursive/-r, --tree, or --map flag", path)
}
// calculate directory depth from base
// depth := strings.Count(path[len(p):], string(filepath.Separator))View on GitHub (pinned to e2d772072e)
Solutions
- Check that the reported path and the parent path are both valid, existing paths
- Run the command from the project root with relative paths instead of mixed absolute paths
- Fix symlink/permission issues on the directories involved
Example fix
// before
found, err = fs.IsSubpathOf(p, path, baseDir)
if err != nil {
return nil, fmt.Errorf("error checking if %s is a subpath of %s: %s", path, p, err)
}
// after — validate inputs up front
if _, err := os.Stat(baseDir); err != nil {
return nil, fmt.Errorf("base directory %s is not accessible: %w", baseDir, err)
}
found, err = fs.IsSubpathOf(p, path, baseDir)
if err != nil {
return nil, fmt.Errorf("error checking if %s is a subpath of %s: %w", path, p, err)
} Defensive patterns
Strategy: validation
Validate before calling
func validatePaths(paths []string, baseDir string) error {
for _, p := range paths {
if !filepath.IsAbs(p) && !strings.HasPrefix(p, baseDir) {
p = filepath.Join(baseDir, p)
}
if _, err := os.Stat(p); err != nil {
return fmt.Errorf("path %s invalid: %w", p, err)
}
}
return nil
} Type guard
func isUsablePath(p string) bool {
info, err := os.Stat(p)
return err == nil && (info.Mode().IsRegular() || info.IsDir())
} Try / catch
resolved, err := ParseInputPaths(raw, baseDir, params)
if err != nil {
if strings.Contains(err.Error(), "is a subpath of") {
fmt.Printf("bad path argument: %v\n", err)
os.Exit(2)
}
return err
} Prevention
- Use clean relative paths from the project root
- Avoid passing paths with shell-expanded globs that may not exist
- Keep symlinks in the repo valid
When it happens
Trigger: fs.IsSubpathOf(p, path, baseDir) returns an error while iterating fileOrDirPaths — usually on invalid path strings, unreadable directories needing evaluation, or malformed relative/absolute mixes.
Common situations: Passing a path containing invalid characters or NUL bytes; baseDir no longer existing (deleted working directory); symlinks that cannot be resolved due to permissions.
Related errors
- error getting parent project ids with paths: %v
- error getting child project ids with paths: %v
- file does not exist: %s
- no project root found
- failed to stat stdin: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/2ad1bbc02517ef73.
Report an issue: GitHub.