JuliusBrussee/caveman · error

native runtime remove stale socket: %w

Error message

native runtime remove stale socket: %w

What it means

ServeUnix found an existing filesystem entry at the socket path, verified via a 50ms dial that no live listener answers (stale), and then os.Remove of that stale entry failed. Typically the entry is owned by another user, the directory denies write (unlink) permission, or the entry is a directory rather than a socket file.

Source

Thrown at proxy/internal/nativeruntime/server_unix.go:49

// the coding agent or the provider proxy.
func ServeUnix(ctx context.Context, path string, runtime *Runtime) error {
	if runtime == nil || runtime.store == nil {
		return errors.New("native runtime: store is required")
	}
	if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
		return fmt.Errorf("native runtime mkdir: %w", err)
	}
	if err := os.Chmod(filepath.Dir(path), 0o700); err != nil {
		return fmt.Errorf("native runtime chmod dir: %w", err)
	}
	if _, err := os.Stat(path); err == nil {
		conn, dialErr := net.DialTimeout("unix", path, 50*time.Millisecond)
		if dialErr == nil {
			_ = conn.Close()
			return errors.New("native runtime: socket already active")
		}
		if err := os.Remove(path); err != nil {
			return fmt.Errorf("native runtime remove stale socket: %w", err)
		}
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("native runtime inspect socket: %w", err)
	}
	listener, err := net.Listen("unix", path)
	if err != nil {
		return fmt.Errorf("native runtime listen: %w", err)
	}
	defer listener.Close()
	defer os.Remove(path)
	if err := os.Chmod(path, 0o600); err != nil {
		return fmt.Errorf("native runtime chmod socket: %w", err)
	}
	go func() {
		<-ctx.Done()
		_ = listener.Close()
	}()
	for {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Remove the stale entry as its owner: sudo rm <socket-path>
  2. Give the running user write permission on the socket directory
  3. If the entry is a directory, rmdir it
  4. Clear immutability: sudo chattr -i <socket-path>

Example fix

# before
stale socket owned by root -> Error[1078]

# after
sudo rm /run/caveman/native.sock && systemctl restart caveman-runtime
Defensive patterns

Strategy: retry

Validate before calling

func staleRemovable(p string) bool {
    fi, err := os.Stat(p)
    if err != nil { return false }
    return fi.Mode()&os.ModeSocket != 0 // only auto-remove socket files, never dirs
}

Try / catch

err := nativeruntime.ServeUnix(ctx, path, rt)
if err != nil && strings.Contains(err.Error(), "remove stale socket") {
    os.Remove(path) // as owner / with privileges, then serve again
    err = nativeruntime.ServeUnix(ctx, path, rt)
}

Prevention

When it happens

Trigger: Previous crash under a different user left the socket file; socket dir not writable for unlink; path occupied by a real directory; immutable attribute set.

Common situations: Running the runtime alternately under sudo and normal user; reusing a system /run path with restrictive permissions.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/feb0b6aa1674c235. Report an issue: GitHub.