{"record":{"id":"0d8263352d54b68f","repo":"sipeed/picoclaw","slug":"failed-to-stat-local-command-q-w","errorCode":null,"errorMessage":"failed to stat local command %q: %w","messagePattern":"failed to stat local command %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/mcp/helpers.go","lineNumber":319,"sourceCode":"\t}\n\tif strings.HasPrefix(path, \"~/\") || strings.HasPrefix(path, \"~\\\\\") {\n\t\treturn filepath.Join(home, path[2:])\n\t}\n\treturn path\n}\n\nfunc validateLocalCommandPath(command string) error {\n\tif !isLocalCommandPath(command) {\n\t\treturn nil\n\t}\n\n\tpath := expandHomePath(command)\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\treturn fmt.Errorf(\"local command %q does not exist\", command)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to stat local command %q: %w\", command, err)\n\t}\n\tif info.IsDir() {\n\t\treturn fmt.Errorf(\"local command %q is a directory\", command)\n\t}\n\tif runtime.GOOS != \"windows\" && info.Mode()&0o111 == 0 {\n\t\treturn fmt.Errorf(\"local command %q is not executable\", command)\n\t}\n\treturn nil\n}\n\nfunc defaultServerProbe(\n\tctx context.Context,\n\tname string,\n\tserver config.MCPServerConfig,\n\tworkspacePath string,\n) (probeResult, error) {\n\tmgr := picomcp.NewManager()\n\tdefer func() { _ = mgr.Close() }()","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/mcp/helpers.go#L301-L337","documentation":"While validating a path-like stdio command, os.Stat failed with something other than ErrNotExist (helpers.go:315-320): permission denied on a parent directory in the path, a path that exceeds filesystem limits, or an I/O error from the underlying filesystem. The raw stat error is preserved via %w so errno detail survives.","triggerScenarios":"A parent directory in the path lacks execute/search permission for the current user; an extremely long path; stat on a flaky network mount (EIO, ESTALE).","commonSituations":"Running under a restricted service account; paths under another user's home; NFS/FUSE mounts during hiccups; macOS privacy controls (TCC) denying access to certain folders.","solutions":["Grant search permission on every parent directory: chmod +x on each path component (or adjust ownership)","Shorten or relocate the path — install the binary on PATH and reference it by bare name, which skips path validation entirely","If the path sits on a network mount, wait for it to become healthy or copy the binary to local disk"],"exampleFix":"# before: /opt/tools is not traversable by $USER\npicoclaw mcp add s /opt/tools/server\n# after\nsudo chmod o+x /opt/tools\npicoclaw mcp add s /opt/tools/server","handlingStrategy":"validation","validationCode":"path=./tools/mcp-serve\nif ! out=$(stat -L \"$path\" 2>&1); then\n  echo \"cannot stat $path: $out\" >&2   # surfaces EACCES/ENAMETOOLONG/EIO before picoclaw does\n  exit 1\nfi\npicoclaw mcp add s \"$path\"","typeGuard":null,"tryCatchPattern":"if err := addCmd.Execute(); err != nil {\n\tif strings.Contains(err.Error(), \"failed to stat local command\") {\n\t\t// os.Stat error is wrapped with %w: check fs.ErrPermission first\n\t\tif errors.Is(err, fs.ErrPermission) {\n\t\t\tfmt.Fprintln(os.Stderr, \"fix search (x) permission on parent directories\")\n\t\t}\n\t\treturn err\n\t}\n}","preventionTips":["Ensure the runtime user has execute (search) permission on every parent directory of the command path","Prefer installing servers on PATH and referencing them by bare name to skip path stat entirely","Avoid registering binaries on flaky network mounts"],"tags":["cli","mcp","stdio","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}