{"record":{"id":"8d0298f761f6bc5b","repo":"sipeed/picoclaw","slug":"local-command-q-is-not-executable","errorCode":null,"errorMessage":"local command %q is not executable","messagePattern":"local command %q is not executable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/mcp/helpers.go","lineNumber":325,"sourceCode":"\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() }()\n\n\tserver.Enabled = true\n\tmcpCfg := config.MCPConfig{\n\t\tToolConfig: config.ToolConfig{Enabled: true},\n\t\tServers: map[string]config.MCPServerConfig{\n\t\t\tname: server,","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/mcp/helpers.go#L307-L343","documentation":"Thrown by validateLocalCommandPath when a local MCP server command resolves to a regular file with no execute permission. On non-Windows platforms picoclaw checks info.Mode()&0o111 — none of the owner/group/other execute bits is set — meaning the OS would refuse to exec the file, so picoclaw fails fast instead of spawning. The check is skipped on Windows, where execute bits do not apply.","triggerScenarios":"A path-like command that exists as a file with a mode such as -rw-r--r--: a downloaded release binary never chmod-ed, a file extracted from an archive that lost permission bits, or a file on a mount without Unix exec semantics (FAT/NTFS, some WSL /mnt paths).","commonSituations":"curl-ing a binary from GitHub releases and forgetting chmod +x; unzipping a server distribution with permissions stripped; WSL accessing Windows mounts; CI artifacts copied with cp without -p.","solutions":["Run chmod +x <command-path>, then retry picoclaw mcp test <name>","Verify with ls -l <command-path> — at least one x must appear in the mode column","If the file sits on a noexec or permission-stripping mount, move it to ~/.local/bin and chmod there","Reinstall through a package manager (npm i -g, pipx install, go install) so permissions are set correctly"],"exampleFix":"# before\n$ ls -l ./mcp-server\n-rw-r--r-- 1 dev dev 12M ./mcp-server\n$ picoclaw mcp test weather\nlocal command \"./mcp-server\" is not executable\n\n# after\n$ chmod +x ./mcp-server\n$ picoclaw mcp test weather","handlingStrategy":"validation","validationCode":"info, err := os.Stat(commandPath)\nif err == nil && !info.IsDir() && runtime.GOOS != \"windows\" && info.Mode()&0o111 == 0 {\n  return fmt.Errorf(\"%s has no execute permission; run chmod +x %s\", commandPath, commandPath)\n}","typeGuard":"func isNotExecutableError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"local command\") && strings.Contains(err.Error(), \"is not executable\")\n}","tryCatchPattern":"if err := runMCPAdd(cfg); err != nil {\n  if isNotExecutableError(err) {\n    // offer to run chmod +x on the detected path, then retry\n  }\n  return err\n}","preventionTips":["After downloading any server binary, chmod +x it before configuring picoclaw","Avoid placing servers on FAT/NTFS or noexec mounts","Prefer package-manager installs (npm i -g, pipx) which set execute bits for you"],"tags":["filesystem","permissions","mcp","config","cli"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}