Troubleshooting
HORUS ships three utility scripts: install.sh, uninstall.sh, and uninstall.ps1 for Windows PowerShell (no bash or MSYS2 needed). This page covers updating, recovering from a broken installation, and debugging HORUS applications at runtime.
Quick Reference
| Script | Use When | What It Does |
|---|---|---|
./install.sh | Install or update | Full installation from source |
./uninstall.sh | Remove HORUS (Linux/macOS) | Complete removal |
.\uninstall.ps1 | Remove HORUS (Windows) | Complete removal, native PowerShell |
Quick Diagnostic Steps
When your HORUS application isn't working:
- Check the Monitor: Run
horus monitorto see active nodes, topics, and message flow. The monitor ships as a plugin — if it reports "The monitor plugin is not installed", runhorus install horus-monitorfirst. - Examine Logs: Look for error messages in your terminal output
- Verify Topics: Ensure publisher and subscriber use exact same topic names
- Check Shared Memory: Look in
/dev/shm/horus_default/(or/dev/shm/horus_*/) for stale HORUS memory regions - Test Individually: Run nodes one at a time to isolate the problem
Updating HORUS
To update to the latest version:
cd /path/to/horus
git pull
./install.sh
To preview changes before updating:
git fetch
git log HEAD..@{u} # See what's new
git pull
./install.sh
If you have uncommitted changes:
git stash
git pull
./install.sh
git stash pop # Restore your changes
Manual Recovery
Use when: Build errors, corrupted cache, installation broken
Quick Steps
# Navigate to HORUS source directory
cd /path/to/horus
# 1. Clean build artifacts
cargo clean
# 2. Remove the cached HORUS source — both roots `horus run` searches
rm -rf ~/.horus/cache # what install.sh writes: horus@<version> + pre-compiled deps
rm -rf ~/.cache/horus # XDG cache root — searched first by `horus run`
# 3. Fresh install
./install.sh
When to Use Recovery
Symptoms requiring recovery:
-
Build fails:
error: could not compile `horus_core` -
Corrupted cache:
error: failed to load source for dependency `horus_core` -
Binary doesn't work:
$ horus --help Segmentation fault -
Version mismatches:
error: the package `horus` depends on `horus_core 0.1.0`, but `horus_core 0.1.3` is installed -
Broken after system updates:
- Rust updated
- System libraries changed
- GCC/Clang updated
What Gets Removed
By cargo clean:
target/directory (build artifacts)
By rm -rf ~/.horus/cache and rm -rf ~/.cache/horus:
- The cached HORUS source tree (
horus@<version>/) and its pre-compiled deps - Cached packages downloaded from the registry
Never removed by the steps above (safe):
~/.horus/config.toml(user settings)~/.config/horus/auth.json(registry auth, on Linux)- Project-local
.horus/directories - Your source code
Full Reset (Nuclear Option)
If the quick steps don't work, do a complete reset:
# Remove everything HORUS-related
cargo clean
rm -rf ~/.horus # installer's source cache (horus@<version>), recordings, env files
rm -rf ~/.config/horus # registry credentials live here, not under ~/.horus
rm -rf ~/.cache/horus # XDG cache root — searched first by `horus run`
rm -f ~/.cargo/bin/horus
# Fresh install
./install.sh
Installation Issues
Problem: "Rust not installed"
$ ./install.sh
Error: Rust is not installed
Solution:
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Then try again
./install.sh
Problem: "C compiler not found"
Solution:
# Ubuntu/Debian/Raspberry Pi OS - Install ALL required packages
sudo apt update
sudo apt install -y build-essential pkg-config \
libssl-dev libudev-dev libasound2-dev \
libx11-dev libxrandr-dev libxi-dev libxcursor-dev libxinerama-dev \
libwayland-dev wayland-protocols libxkbcommon-dev \
libvulkan-dev libfontconfig-dev libfreetype-dev \
libv4l-dev
# Fedora/RHEL
sudo dnf groupinstall "Development Tools"
sudo dnf install -y pkg-config openssl-devel systemd-devel alsa-lib-devel \
libX11-devel libXrandr-devel libXi-devel libXcursor-devel libXinerama-devel \
wayland-devel wayland-protocols-devel libxkbcommon-devel \
vulkan-devel fontconfig-devel freetype-devel \
libv4l-devel
Problem: Build fails with linker errors
error: linking with `cc` failed: exit status: 1
error: could not find native static library `X11`, perhaps an -L flag is missing?
Solution:
# Install ALL missing system libraries (most common cause)
# Ubuntu/Debian/Raspberry Pi OS
sudo apt update
sudo apt install -y build-essential pkg-config \
libssl-dev libudev-dev libasound2-dev \
libx11-dev libxrandr-dev libxi-dev libxcursor-dev libxinerama-dev \
libwayland-dev wayland-protocols libxkbcommon-dev \
libvulkan-dev libfontconfig-dev libfreetype-dev \
libv4l-dev
# Or run manual recovery (see Manual Recovery section)
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh
Update Issues
Problem: "Build failed" during update
Solution:
# Try manual recovery
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh
Problem: "Already up to date" but binary broken
Solution:
# Force rebuild
./install.sh
Runtime Issues
"horus: command not found"
Solution:
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.cargo/bin:$PATH"
# Then reload shell
source ~/.bashrc # or restart terminal
# Verify
which horus
horus --help
Binary exists but doesn't run
$ horus --help
Segmentation fault
Solution:
# Full recovery
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh
Version mismatch errors
error: the package `horus` depends on `horus_core 0.1.0`,
but `horus_core 0.1.3` is installed
Why this happens:
- You updated the
horusCLI to a new version - Your project's
.horus/directory still has cached dependencies from the old version - The cached
Cargo.lockreferences incompatible library versions
Option 1: horus run --clean (recommended - fast & easy)
# Clean cached build artifacts and dependencies
horus run --clean
# This clears .horus/cache/, .horus/bin/ and any top-level target/,
# forcing a fresh build with the new version.
# Note: it does NOT remove .horus/target/ — see Option 2 for that.
Alternative Solutions:
Option 2: Manual cleanup
# Remove the entire .horus directory
rm -rf .horus/
# Next run will rebuild from scratch
horus run
Option 3: Manual recovery (for persistent issues)
# Only needed if --clean doesn't work
# This reinstalls HORUS libraries globally
cd /path/to/horus
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh
For multiple projects:
# Clean all projects in your workspace
find ~/your-projects -type d -name ".horus" -exec rm -rf {}/target/ \;
"HORUS source not found" (Rust projects)
Error: HORUS source not found. This can happen after running 'horus clean -a'.
To fix this, either:
1. Re-run the install script: ./install.sh (or curl the installer)
2. Set HORUS_SOURCE environment variable to your HORUS source directory
3. Clone HORUS to ~/softmata/horus or ~/horus
Solution:
# Option 1: Set HORUS_SOURCE (recommended for non-standard installations)
export HORUS_SOURCE=/path/to/horus
echo 'export HORUS_SOURCE=/path/to/horus' >> ~/.bashrc
# Option 2: Install HORUS to a standard location
# The CLI checks these paths automatically, in order:
# - /horus
# - ~/softmata/horus
# - ~/horus
# - /opt/horus
# - /usr/local/horus
#
# It also falls back to the installer's source cache, which has two roots
# (the exact-version directory is preferred, then any horus@* tree):
# - ~/.cache/horus/horus@<version> (XDG: $XDG_CACHE_HOME/horus, or ~/Library/Caches/horus on macOS)
# - ~/.horus/cache/horus@<version> (what install.sh actually writes)
# Verify HORUS source is found
horus build
Why this happens:
horus runneeds to find HORUS core libraries for Rust compilation- It auto-detects standard installation paths
- For custom installations, set
$HORUS_SOURCE
Topic Creation Errors
Symptom: Application crashes on startup with:
Error: Failed to create `Topic<MyMessage>`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value'
Common Causes:
-
Stale Shared Memory from Previous Run
- HORUS uses the
/dev/shm/horus_<namespace>/directory for communication (horus_defaultunlessHORUS_NAMESPACEis set) - If your app crashes, these files persist
Fix: Clean shared memory:
# Remove all HORUS shared memory (scans every horus_* namespace) horus clean --shm - HORUS uses the
-
Insufficient Permissions on
/dev/shmFix: Check permissions:
ls -la /dev/shm/horus_default/topics/ # Should show your user as owner # If not, remove with sudo sudo rm -rf /dev/shm/horus_default/ # Fix permissions (if needed) sudo chmod 1777 /dev/shm -
Disk Space Full on
/dev/shmFix: Check available space:
df -h /dev/shm -
Conflicting Topic Names
- Two Topics with same name but different types
Fix: Use unique topic names:
// BAD: Same name, different types let topic1: Topic<f32> = Topic::new("data")?; let topic2: Topic<String> = Topic::new("data")?; // CONFLICT! // GOOD: Different names let topic1: Topic<f32> = Topic::new("sensor_data")?; let topic2: Topic<String> = Topic::new("status_data")?;
General Code Fix:
// Topic names become file paths on the underlying shared memory system.
// Use simple, descriptive names with dots (not slashes):
let topic = Topic::new("sensor_data")?;
let topic = Topic::new("camera.front.raw")?;
"No such file or directory" when creating Topic
Symptom: Application crashes with:
thread 'main' panicked at 'Failed to create publisher 'camera': No such file or directory'
Cause: You're using slashes (/) in your topic name. While slashes work on Linux (parent directories are created automatically), they fail on macOS where shared memory uses shm_open() which doesn't support embedded slashes.
HORUS topic names map to files under /dev/shm/horus_<namespace>/topics/ on Linux (the namespace is default unless HORUS_NAMESPACE is set):
Topic: "sensors.camera" → /dev/shm/horus_default/topics/sensors.camera (cross-platform)
Topic: "sensors/camera" → /dev/shm/horus_default/topics/sensors/camera (Linux only, fails on macOS)
Fix: Use dots instead of slashes for cross-platform compatibility:
// NOT RECOMMENDED - fails on macOS
let topic: Topic<f32> = Topic::new("sensors/camera")?;
let topic: Topic<Twist> = Topic::new("robot/cmd_vel")?;
// RECOMMENDED - works on all platforms
let topic: Topic<f32> = Topic::new("sensors.camera")?;
let topic: Topic<Twist> = Topic::new("robot.cmd_vel")?;
Coming from ROS? ROS uses slashes (/sensor/lidar) because it uses network-based naming. HORUS uses dots because topic names map directly to shared memory file names. See Topic Naming for details.
Topic Not Found / No Messages Received
Symptom: Subscriber node never receives messages even though publisher is sending.
// recv() always returns None
if let Some(data) = self.data_sub.recv() {
println!("Got data"); // Never prints
}
Common Causes:
-
Topic Name Mismatch (Typo)
- This is the #1 cause
Fix: Verify exact topic names:
// Publisher let pub_topic: Topic<f32> = Topic::new("sensor_data")?; // Note: sensor_data // Subscriber (TYPO! Missing underscore) let sub_topic: Topic<f32> = Topic::new("sensordata")?; // CORRECT: let sub_topic: Topic<f32> = Topic::new("sensor_data")?; // Exact matchDebug with Monitor:
horus monitorCheck the "Topics" section to see active topic names.
-
Publisher Hasn't Sent Yet
- Subscriber starts before publisher sends first message
- This is normal! First
recv()will returnNone
Fix: Check multiple ticks:
impl Node for SubscriberNode { fn tick(&mut self) { if let Some(msg) = self.topic.recv() { // Process message } else { // No message yet - this is OK on first few ticks } } } -
Wrong Priority Order
- Subscriber runs before publisher in same tick
Fix: Set priorities correctly:
// Publisher should run first (lower order number) scheduler.add(PublisherNode::new()?).order(0).done(); // Subscriber runs after (higher order number) scheduler.add(SubscriberNode::new()?).order(1).done();
"Type mismatch on topic ..."
A type mismatch is not a cause of silence — it fails loudly, at construction,
before recv() is ever reached. It gets its own section because it is easy to
mistake for a delivery problem.
Symptom: Topic::new() returns an error on startup:
Communication error: Failed to create topic 'data': type mismatch. Existing type 'f32', attempted 'f64'.
Two processes opened the same topic with different message types.
Fix: use distinct topic names for different message types.
Cause: A topic's message type is fixed by whichever process creates it first. Opening the same name with a different type is rejected, so you get an error rather than zero messages.
Fix: Use the same type on both sides, or pick distinct topic names:
// Publisher
let pub_topic: Topic<f32> = Topic::new("data")?;
pub_topic.send(3.14);
// Subscriber (WRONG TYPE) — Topic::new returns Err here
let sub_topic: Topic<f64> = Topic::new("data")?; // f64 != f32
// CORRECT:
let sub_topic: Topic<f32> = Topic::new("data")?; // Same type
Application Hangs / Deadlock
Symptom: Your app starts but freezes with no error messages.
Starting application...
[Nodes initialized]
[Application freezes - no output]
Common Causes:
-
Infinite Loop in
tick()// BAD: Never returns! fn tick(&mut self) { loop { // Process data } } // GOOD: Tick returns after work fn tick(&mut self) { self.process_data(); // Return naturally — scheduler calls tick() again next frame } -
Blocking Operations in
tick()// BAD: Blocks scheduler fn tick(&mut self) { std::thread::sleep(Duration::from_secs(10)); // Blocks everything! } // GOOD: Use tick counter for delays fn tick(&mut self) { self.tick_count += 1; // Execute every 10 ticks (~100ms at the default 100 Hz tick rate) if self.tick_count % 10 == 0 { self.slow_operation(); } } -
Waiting Forever for Messages
// BAD: Blocking wait fn tick(&mut self) { while self.data_sub.recv().is_none() { // Infinite loop if no messages! } } // GOOD: Non-blocking receive fn tick(&mut self) { if let Some(data) = self.data_sub.recv() { // Process data } // Continue even if no message } -
Circular Priority Dependencies
- Node A waits for Node B, Node B waits for Node A
Fix: Ensure data flows one direction:
// BAD: Circular dependency // Node A (priority 0) subscribes to "data_b" // Node B (priority 1) subscribes to "data_a" // Both wait for each other! // GOOD: Unidirectional flow // Node A (priority 0) publishes to "data_a" // Node B (priority 1) subscribes to "data_a", publishes to "data_b" // Node C (priority 2) subscribes to "data_b" -
Debug with Logging
fn tick(&mut self) { hlog!(debug, "Tick started"); // Your code here hlog!(debug, "Tick completed"); }If you see "Tick started" but never "Tick completed", the hang is in your code.
Messages Silently Dropped
Symptom: Publisher sends messages but subscriber never receives them, and no error is reported.
Cause: send() is lossy. The usual cause is a full ring buffer — the subscriber isn't draining it fast enough. When the ring is full, send() retries briefly (one immediate retry, then 64 spins and 4 yields) and then drops the message, incrementing the topic's drop counter.
Message size alone rarely causes drops: serialized payloads larger than 4KB are spilled to a shared TensorPool automatically, and a payload that still exceeds the current slot (default 8KB) triggers an automatic slot grow followed by a retry.
A second cause, which dropped_count() cannot see: on a broadcast POD topic
(PodShm — a fixed-size message with more than one subscriber) the producer never
fails to send. It overwrites the oldest slot instead. A consumer that falls a full
ring behind is lapped: it detects the overwrite, resumes roughly half a ring back
from the head, and the messages in between are gone. This loss happens on the
receive side, so the publisher's dropped_count() stays at 0 throughout. If
messages are vanishing on a multi-subscriber topic while the drop counter reads
zero, this is why — the fix is the same as below, drain faster or publish slower.
Fix:
1. Confirm the drops and count them:
// dropped_count() = send() calls that gave up after the bounded retry
if self.topic.dropped_count() > 0 {
hlog!(warn, "{} messages dropped on '{}'",
self.topic.dropped_count(), self.topic.name());
}
This counter is per-process and lives in the publishing process — it is not
written to shared memory, so read it from the node that owns the topic rather
than looking for it in horus monitor. (From Python: topic.stats()["send_failures"].)
2. Let the subscriber drain the ring:
Give the subscriber a tick rate at least as high as the publisher's:
scheduler.add(PublisherNode::new()?).order(0).rate(50_u64.hz()).done()?;
scheduler.add(SubscriberNode::new()?).order(1).rate(200_u64.hz()).done()?;
Or drain everything queued on each tick instead of a single message:
fn tick(&mut self) {
while let Some(msg) = self.topic.recv() {
self.process(msg);
}
}
3. Give a bursty publisher a deeper ring:
// Default capacity is one 4KB page worth of slots, clamped to 16..=1024
// and rounded up to a power of two. Ask for more explicitly:
let topic: Topic<SensorData> = Topic::with_capacity("sensor_data", 1024, None)?;
4. For messages you cannot afford to lose on a point-to-point topic, use send_blocking():
(It applies no backpressure on a broadcast topic — those overwrite rather than fill, so the call returns immediately. There, the fix is a faster consumer or a deeper ring.)
use std::time::Duration;
// Waits for space instead of dropping; Err(SendBlockingError::Timeout)
// if the ring stayed full for the whole timeout
if let Err(e) = self.cmd_topic.send_blocking(cmd, Duration::from_millis(5)) {
hlog!(error, "cmd_vel send timed out: {}", e);
}
If you suspect an oversized payload instead, message size rarely causes drops (see above), but you can check it directly:
use std::mem::size_of;
// POD messages always fit (slot = size_of::<T>())
// Non-POD messages are serialized; payloads over 4KB are spilled to a TensorPool
println!("Message size: {} bytes", size_of::<MyMessage>());
A #[repr(C)] #[derive(Clone, Copy)] POD message skips serialization on the hot path — the ring slot is a memcpy of T — but Clone + Serialize + Deserialize are still required trait bounds on every message type, so the derives stay. If you keep a serde message with a large fixed array, note that serde only derives for arrays up to length 32 — longer ones need serde_arrays (add serde_arrays = "0.2" to your dependencies):
#[derive(Clone, Serialize, Deserialize)]
pub struct LargeMessage {
#[serde(with = "serde_arrays")]
pub data: [u8; 4096], // Fixed 4KB
}
Build and Compilation Issues
"unresolved import" or "cannot find type in this scope"
Symptom: Code won't compile, missing types or functions.
Fix: Add HORUS to horus.toml:
[dependencies]
horus = "*"
Import the prelude:
use horus::prelude::*; // Provides Twist, LaserScan, CmdVel, etc.
horus::prelude::* re-exports the standard robotics messages (CmdVel, Twist, Imu,
LaserScan, BatteryState, …), so horus is the only dependency you need — there is no
separate message crate to add.
"trait bound ... is not satisfied"
Symptom: Compiler says your message doesn't implement required traits.
Fix: Add required derives:
// Clone + Serialize + Deserialize are required on every message
// (Debug is optional, but worth having)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MyMessage {
pub field: f32,
}
Performance Issues
Problem: Slow builds
Solution:
# Use release mode (optimized)
horus run --release
Problem: Large disk usage
Solution:
# Clean old cargo cache
cargo clean
# Remove unused dependencies
cargo install cargo-cache
cargo cache --autoclean
Problem: Large .horus/target/ directory (Rust projects)
Why this happens:
- Cargo stores build artifacts in
.horus/target/ - Debug builds are unoptimized and larger
- Incremental compilation caches intermediate files
Solution:
# Clean build artifacts in current project
# (no built-in command reclaims .horus/target/ —
# neither `horus run --clean` nor `horus clean` touches it)
rm -rf .horus/target/
# Regular cleanup (if working on multiple projects)
find . -type d -name ".horus" -exec rm -rf {}/target/ \;
# Add to .gitignore (already included in horus new templates)
echo ".horus/target/" >> .gitignore
Disk usage typical sizes:
.horus/Cargo.toml: ~266 bytes.horus/target/debug/: ~10-100 MB (incremental builds).horus/target/release/: ~5-50 MB (optimized, no debug symbols)
Best practices:
.horus/target/is in.gitignoreby default- Clean periodically if disk space is limited
- Only
.horus/Cargo.tomland.horus/Cargo.lockare needed for rebuild
Using the Monitor to Debug
The monitor is your best debugging tool for runtime issues.
Starting the Monitor:
# Terminal 1: Run your application
horus run
# Terminal 2: Start monitor
horus monitor
The monitor ships as a plugin. If horus monitor reports "The monitor plugin is not installed", install it first with horus install horus-monitor.
Monitor Features:
1. Nodes Tab:
- Shows all running nodes
- Displays node state (Running, Error, Stopped)
- Shows tick count and timing
- Highlights nodes that aren't ticking (stuck)
2. Topics Tab:
- Lists all active topics
- Shows message types
- Displays publisher/subscriber counts
- 0 publishers = no one is sending
- 0 subscribers = no one is listening
3. Metrics Tab:
- IPC Latency: Communication time (should be <1µs)
- Tick Duration: How long each node takes
- Message Counts: Total sent/received
- If sent > 0 but received = 0, subscriber issue
- If sent = 0, publisher issue
4. Graph Tab:
- Visual node graph
- Shows message flow between nodes
- Disconnected nodes = topic mismatch
Debug Workflow:
1. Check Nodes tab
-> All nodes Running? (If Error, check logs)
2. Check Topics tab
-> Topics exist? (If no, topic name typo)
-> Publishers > 0? (If no, publisher not working)
-> Subscribers > 0? (If no, subscriber not created)
3. Check Metrics tab
-> Messages sent > 0? (If no, publisher not sending)
-> Messages received > 0? (If no, subscriber not receiving)
-> IPC latency sane? (If >1ms, system issue)
4. Check Graph tab
-> Nodes connected? (If no, topic name mismatch)
Example Debug Session:
# Problem: Subscriber not receiving messages
# Monitor shows:
# Nodes: SensorNode (Running), DisplayNode (Running)
# Topics: "sensor_data" (1 pub, 0 sub) <-- AHA!
# Issue: No subscribers!
# Fix: Check DisplayNode - likely wrong topic name
Reading Log Output
Log Levels
HORUS nodes can log at different severity levels:
fn tick(&mut self) {
hlog!(debug, "Detailed info for debugging");
hlog!(info, "Normal informational message");
hlog!(warn, "Something unusual happened");
hlog!(error, "Something went wrong!");
}
Log Format
Console output uses ANSI-colored formatting:
[INFO] [SensorNode] Sensor initialized
│ │ │
│ │ └─ Message
│ └─ Node name
└─ Log level (INFO, WARN, ERROR, DEBUG)
Timestamps are included in the shared memory log buffer (visible in the monitor), formatted as HH:MM:SS.mmm.
Common Patterns and Anti-Patterns
[OK] DO: Check recv() for None
fn tick(&mut self) {
if let Some(msg) = self.topic.recv() {
// Process message
}
// No message? That's OK, just continue
}
[FAIL] DON'T: Unwrap recv()
fn tick(&mut self) {
let msg = self.topic.recv().unwrap(); // PANIC if no message!
}
[OK] DO: Use Result for errors
impl Node for MyNode {
fn init(&mut self) -> Result<()> {
if self.sensor.is_broken() {
return Err(Error::node("MyNode", "Sensor initialization failed"));
}
Ok(())
}
}
[FAIL] DON'T: panic!() in nodes
fn init(&mut self) -> Result<()> {
if self.sensor.is_broken() {
panic!("Sensor broken"); // DON'T DO THIS
}
Ok(())
}
[OK] DO: Keep tick() fast
fn tick(&mut self) {
// Quick operations only
let data = self.sensor.read_cached();
self.topic.send(data);
}
[FAIL] DON'T: Block in tick()
fn tick(&mut self) {
thread::sleep(Duration::from_millis(100)); // Blocks everything!
let data = self.network.fetch(); // Network I/O blocks!
}
Best Practices
Regular Maintenance
Weekly (active development):
git pull && ./install.sh # Pulls latest and rebuilds
After system updates:
# If Rust/GCC updated, run manual recovery
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh
CI/CD Integration
# In CI pipeline
./install.sh || (cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh)
Debugging Workflow
-
First: Check horus works
horus --help -
If issues: Update
git pull && ./install.sh -
If errors: Manual recovery
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh
Getting Help
If you're still having issues:
-
Try manual recovery:
cargo clean && rm -rf ~/.horus/cache ~/.cache/horus && ./install.sh -
Add Debug Logging:
// Add hlog!(debug, ...) in your nodes to trace execution hlog!(debug, "Node state: {:?}", self.state); -
Test with Minimal Example:
- Strip down to simplest possible code
- Add complexity back one piece at a time
- Identify what causes the error
-
Check System Resources:
# Check available shared memory df -h /dev/shm # Check HORUS files ls -lh /dev/shm/horus_default/topics/ # Clean if needed (scans every horus_* namespace) horus clean --shm -
Report the issue:
- GitHub: https://github.com/softmata/horus/issues
- Include: full error message, minimal code example, OS and platform
Next Steps
- Installation - First-time installation guide
- CLI Reference - All horus commands
- Examples - Working code examples
- Performance - Optimization tips
- Testing - Test your nodes to prevent runtime errors