claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Bundled ripgrep fails on Raspberry Pi 5 due to jemalloc page size mismatch

Open hydrohelix opened this issue 3 months ago • 8 comments

Bug Report: Bundled ripgrep fails on Raspberry Pi 5 due to jemalloc page size mismatch

Summary

Custom slash commands in Claude Code fail to load on Raspberry Pi 5 (and potentially other 16KB page size ARM systems) because the bundled ripgrep binary was compiled with jemalloc configured for 4KB pages.

Environment

  • Device: Raspberry Pi 5 Model B Rev 1.1
  • OS: Debian GNU/Linux 12 (bookworm)
  • Kernel: 6.12.47+rpt-rpi-2712
  • Architecture: aarch64
  • Page Size: 16384 bytes (16KB)
  • Claude Code Version: 2.0.14

Steps to Reproduce

  1. Install Claude Code on Raspberry Pi 5
  2. Create custom slash commands in .claude/commands/ with proper frontmatter
  3. Start Claude Code session
  4. Try to use custom slash commands (e.g., /my-command)
  5. Commands are not recognized

Root Cause

The bundled ripgrep binary at ~/.claude/local/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-linux/rg fails with jemalloc error:

<jemalloc>: Unsupported system page size
memory allocation of 160 bytes failed

This occurs because:

  1. The binary was compiled with jemalloc configured for 4KB pages (common in cloud/server ARM systems)
  2. Raspberry Pi 5 uses 16KB pages (via getconf PAGESIZE = 16384)
  3. jemalloc's internal structures are sized at compile-time based on page size
  4. When there's a mismatch, memory allocation fails immediately

Impact

  • Custom slash commands don't load - The command scanning process silently fails
  • No error shown to user - The failure happens during startup and is only visible in debug logs
  • Affects all 16KB page ARM systems - Not just Raspberry Pi 5

Debug Log Evidence

From ~/.claude/debug/*.txt:

[ERROR] Error: Command failed: /home/pi/.claude/local/.../rg --files --hidden --follow --glob *.md /path/.claude/commands
[DEBUG] Total plugin commands loaded: 0
[DEBUG] Slash commands included in SlashCommand tool:

Workaround

Replace the bundled ripgrep with a symlink to system ripgrep (compiled for correct page size):

# Backup broken binary
mv ~/.claude/local/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-linux/rg \
   ~/.claude/local/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-linux/rg.broken

# Link to system ripgrep
ln -s /usr/bin/rg \
   ~/.claude/local/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-linux/rg

Or use the automated fix script:

#!/bin/bash
# fix_claude_ripgrep.sh
set -e

RIPGREP_PATH="$HOME/.claude/local/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-linux"
RIPGREP_BINARY="$RIPGREP_PATH/rg"
SYSTEM_RIPGREP="/usr/bin/rg"

# Check page size
PAGE_SIZE=$(getconf PAGESIZE)
if [ "$PAGE_SIZE" != "16384" ]; then
    echo "Page size is ${PAGE_SIZE} bytes, not 16KB. No fix needed."
    exit 0
fi

# Check if already fixed
if [ -L "$RIPGREP_BINARY" ]; then
    echo "Already fixed: $(readlink -f "$RIPGREP_BINARY")"
    exit 0
fi

# Apply fix
[ -f "$RIPGREP_BINARY" ] && mv "$RIPGREP_BINARY" "$RIPGREP_BINARY.broken"
ln -s "$SYSTEM_RIPGREP" "$RIPGREP_BINARY"
echo "Fix applied! Restart Claude Code for custom slash commands to load."

Suggested Solutions

Option 1: Compile for 16KB pages (Quick Fix) Compile the arm64-linux ripgrep binary with jemalloc configured for 16KB pages, or use the system allocator instead of jemalloc.

Option 2: Bundle both versions (Better)

  • Bundle both arm64-linux-4k/rg and arm64-linux-16k/rg
  • Detect page size at runtime and use appropriate binary

Option 3: Fallback to system ripgrep (Best)

  • Detect if bundled ripgrep fails
  • Automatically fallback to system ripgrep if available
  • Show warning if neither works

Option 4: Drop bundled ripgrep for ARM (Pragmatic)

  • Check for system ripgrep on ARM systems during installation
  • Only bundle ripgrep for platforms where it's commonly missing (Windows, older systems)

Why This Matters

  • Apple Silicon Macs work fine - The arm64-darwin binary is properly compiled for 16KB pages
  • Growing ARM adoption - More developers using Raspberry Pi, ARM servers, Apple Silicon
  • Silent failure - Users don't know why their custom commands don't work

Related Issues

This is distinct from:

  • #3569 (aarch64 architecture detection) - That's about installation
  • #2151 (MCP servers on Pi) - That's about MCP, not core ripgrep functionality
  • Other ripgrep issues - Those are about usage, not compilation incompatibility

Additional Context

  • System ripgrep (/usr/bin/rg version 13.0.0) works perfectly on the same system
  • The issue persists across Claude Code updates (binary is re-bundled each time)
  • This affects any functionality that relies on ripgrep for file scanning

hydrohelix avatar Oct 13 '25 08:10 hydrohelix

Better Solution: Compile with Higher lg-page Value

A superior fix has been identified: compile the ripgrep binary with jemalloc configured for a higher maximum page size using --with-lg-page.

The Fix

When building ripgrep for arm64-linux, use:

JEMALLOC_SYS_WITH_LG_PAGE=16 cargo build --release

Or for Rust's jemalloc-sys crate:

JEMALLOC_SYS_WITH_LG_PAGE=16

Why This Works

The lg-page parameter sets the logarithm base-2 of the MAXIMUM page size:

  • lg-page=12 → 2^12 = 4KB (current bundled binary)
  • lg-page=14 → 2^14 = 16KB
  • lg-page=16 → 2^16 = 64KB (recommended)

Key benefit: A binary compiled with a higher lg-page value works with all smaller page sizes:

Compiled with 4KB systems 16KB systems 64KB systems
lg-page=12
lg-page=14
lg-page=16

Advantages Over Other Solutions

Compared to symlink workaround:

  • ✅ One binary works everywhere
  • ✅ Survives Claude Code updates
  • ✅ No user intervention needed

Compared to bundling multiple binaries:

  • ✅ Simpler build process
  • ✅ No runtime page size detection needed
  • ✅ Smaller package size

Compared to system ripgrep fallback:

  • ✅ More reliable (system rg might not exist)
  • ✅ Consistent behavior across systems
  • ✅ No version inconsistencies

Trade-offs

  • Memory overhead: ~0.1-0.2MB additional memory usage (negligible)
  • Performance: Essentially unchanged for typical workloads

Recommendation

Compile the arm64-linux ripgrep binary with JEMALLOC_SYS_WITH_LG_PAGE=16 to support:

  • Traditional ARM cloud servers (4KB pages)
  • Raspberry Pi 5 and Apple Silicon (16KB pages)
  • Enterprise ARM systems (64KB pages)

This is a one-line build configuration change that fixes the issue for all ARM Linux systems.

hydrohelix avatar Oct 13 '25 08:10 hydrohelix

I just wanted to add at least one "me too" post so we know its not just @hydrohelix 's issue. I have to implement the workaround every morning before I get started or none of my agents show up in the app.

Thanks for the thorough report, I came here to make one and yours is better than I intended.

ProtoSorcerySteve avatar Oct 24 '25 17:10 ProtoSorcerySteve

👍 I'm having the same issue

jpmarques19 avatar Oct 28 '25 06:10 jpmarques19

I'm having the same issue using Asahi linux. Even with the updated jemalloc, I needed to add to ~/.claude/settings.json

  {
    "env": {
      "USE_BUILTIN_RIPGREP": "0"
    }
  }

schmidtw avatar Oct 29 '25 21:10 schmidtw

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

github-actions[bot] avatar Dec 09 '25 10:12 github-actions[bot]

Still an issue

hydrohelix avatar Dec 09 '25 19:12 hydrohelix

We're also seeing this on an HPC cluster that uses 64KB pages

I'm trying out the USE_BUILTIN_RIPGREP=0 approach for now

jon-aisi avatar Dec 18 '25 00:12 jon-aisi

same issues, and I think one possible solution is providing an option to use our system rg instead of the built-in rg?

LeiWang1999 avatar Dec 23 '25 07:12 LeiWang1999