What
On macOS, net.local.dgram.maxdgram defaults to 2048 bytes, and that's a hard cap on single-datagram payload size for AF_UNIX SOCK_DGRAM. Surfaced during runtime drill of SHIT_TRACK_ENV=1 on bash/zsh/fish — every PreExecEnv / PostExecEnv hook frame fails with EMSGSIZE because a real-user env block (3-5 KB typical) exceeds the cap.
Plain PreExec / PostExec frames are ~80 bytes and unaffected; only the env-block carriers blow up. On Linux/FreeBSD the default cap is much larger, so this doesn't surface in CI's smoke matrix.
Repro
SHIT_TRACK_ENV=1 bash -c 'source <(...)' # real env, not env -i
# daemon receives PreExec/PostExec fine but never sees the *Env frames;
# `shit hook-send pre-exec-env` exits 1 silently due to `>/dev/null 2>&1 || true` in the hook
sysctl net.local.dgram.maxdgram # 2048
Workaround for the drill: env -i PATH=... strip down to a sub-2KB block.
Fix options
- Stream-fallback transport for the env-block messages only — hook socket stays DGRAM for fast small frames; PreExecEnv/PostExecEnv go over a side
SOCK_STREAM (or SEQPACKET) channel.
- Chunked datagrams: split env blocks into N sub-2KB frames with a seq+offset, reassemble daemon-side.
- Bump
net.local.dgram.maxdgram in the install/post-install step — requires sudo, only affects current macOS boot.
- Drop the bytewise mask in
shell/{bash,zsh,fish}.{sh,fish} so users see the error and can opt into option 3.
Option 1 is cleanest; the daemon already runs a STREAM-like helper link, so the wiring shape is precedented.
Touched
crates/shitd/src/server.rs (hook socket bind)
crates/shit/src/send.rs (UnixDatagram::unbound().send_to)
shell/{bash.sh,zsh.sh,fish.fish} (silent-fail mask on env-block sends)
Refs
What
On macOS,
net.local.dgram.maxdgramdefaults to 2048 bytes, and that's a hard cap on single-datagram payload size forAF_UNIX SOCK_DGRAM. Surfaced during runtime drill ofSHIT_TRACK_ENV=1on bash/zsh/fish — everyPreExecEnv/PostExecEnvhook frame fails withEMSGSIZEbecause a real-user env block (3-5 KB typical) exceeds the cap.Plain
PreExec/PostExecframes are ~80 bytes and unaffected; only the env-block carriers blow up. On Linux/FreeBSD the default cap is much larger, so this doesn't surface in CI's smoke matrix.Repro
Workaround for the drill:
env -i PATH=...strip down to a sub-2KB block.Fix options
SOCK_STREAM(or SEQPACKET) channel.net.local.dgram.maxdgramin the install/post-install step — requires sudo, only affects current macOS boot.shell/{bash,zsh,fish}.{sh,fish}so users see the error and can opt into option 3.Option 1 is cleanest; the daemon already runs a STREAM-like helper link, so the wiring shape is precedented.
Touched
crates/shitd/src/server.rs(hook socket bind)crates/shit/src/send.rs(UnixDatagram::unbound().send_to)shell/{bash.sh,zsh.sh,fish.fish}(silent-fail mask on env-block sends)Refs
sysctl net.local.dgram.maxdgramis the canonical macOS knob; not present on Linux/FreeBSD.