sipeed/picoclaw · error
local command %q is not executable
Error message
local command %q is not executable
What it means
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.
Source
Thrown at cmd/picoclaw/internal/mcp/helpers.go:325
func validateLocalCommandPath(command string) error {
if !isLocalCommandPath(command) {
return nil
}
path := expandHomePath(command)
info, err := os.Stat(path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("local command %q does not exist", command)
}
return fmt.Errorf("failed to stat local command %q: %w", command, err)
}
if info.IsDir() {
return fmt.Errorf("local command %q is a directory", command)
}
if runtime.GOOS != "windows" && info.Mode()&0o111 == 0 {
return fmt.Errorf("local command %q is not executable", command)
}
return nil
}
func defaultServerProbe(
ctx context.Context,
name string,
server config.MCPServerConfig,
workspacePath string,
) (probeResult, error) {
mgr := picomcp.NewManager()
defer func() { _ = mgr.Close() }()
server.Enabled = true
mcpCfg := config.MCPConfig{
ToolConfig: config.ToolConfig{Enabled: true},
Servers: map[string]config.MCPServerConfig{
name: server,View on GitHub (pinned to 49183d7e8d)
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
Example fix
# before $ ls -l ./mcp-server -rw-r--r-- 1 dev dev 12M ./mcp-server $ picoclaw mcp test weather local command "./mcp-server" is not executable # after $ chmod +x ./mcp-server $ picoclaw mcp test weather
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(commandPath)
if err == nil && !info.IsDir() && runtime.GOOS != "windows" && info.Mode()&0o111 == 0 {
return fmt.Errorf("%s has no execute permission; run chmod +x %s", commandPath, commandPath)
} Type guard
func isNotExecutableError(err error) bool {
return err != nil && strings.Contains(err.Error(), "local command") && strings.Contains(err.Error(), "is not executable")
} Try / catch
if err := runMCPAdd(cfg); err != nil {
if isNotExecutableError(err) {
// offer to run chmod +x on the detected path, then retry
}
return err
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- failed to save config: %w
- failed to stat local command %q: %w
- local command %q is a directory
- failed to save config: %w
- reset failed: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/8d0298f761f6bc5b.
Report an issue: GitHub.