JuliusBrussee/caveman · error
native runtime chmod dir: %w
Error message
native runtime chmod dir: %w
What it means
ServeUnix enforces 0700 on the socket's parent directory after creating it, because the socket itself carries no other access control until it is chmod'd — a group/world-readable directory would let other local users connect to the runtime. Chmod failure means wrong ownership or a filesystem that does not support mode changes.
Source
Thrown at proxy/internal/nativeruntime/server_unix.go:40
}
// Serve binds runtime transport for current platform.
func Serve(ctx context.Context, home string, runtime *Runtime) error {
return ServeUnix(ctx, SocketPath(home), runtime)
}
// ServeUnix exposes one-request-per-connection JSON over a user-only Unix
// socket. Runtime errors close or fail-open the individual call; they never stop
// 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()View on GitHub (pinned to 27d5a3981a)
Solutions
- chown the socket directory to the runtime user and chmod 700 manually
- Delete the pre-existing directory so ServeUnix recreates it as the running user
- Use a local POSIX filesystem for the socket directory
Example fix
# before sudo mkdir -p /run/caveman # owned by root -> Error[1077] # after sudo chown caveman:caveman /run/caveman && sudo chmod 700 /run/caveman
Defensive patterns
Strategy: validation
Validate before calling
func socketDirTight(p string) bool {
fi, err := os.Stat(filepath.Dir(p))
return err == nil && fi.IsDir() && fi.Mode().Perm() == 0o700
} Prevention
- Systemd units: RuntimeDirectory=caveman with RuntimeDirectoryMode=0700
- Do not pre-create the dir as root for an unprivileged service
- Keep sockets off chmod-ignoring filesystems
When it happens
Trigger: Socket dir pre-created by root while the runtime runs unprivileged; directory on FAT/CIFS or other chmod-ignoring filesystem.
Common situations: Installers creating dirs as root; shared or foreign-mounted volumes.
Related errors
- native runtime mkdir: %w
- native runtime remove stale socket: %w
- native runtime inspect socket: %w
- native runtime chmod socket: %w
- native runtime: socket already active
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/15a6e596400e3c9d.
Report an issue: GitHub.