Skip to content
This repository was archived by the owner on Feb 21, 2026. It is now read-only.

fix: Critical stability improvements from 2026-02-14 audit#19

Merged
Peyton-Spencer merged 2 commits intomainfrom
fix/stability-quick-wins
Feb 14, 2026
Merged

fix: Critical stability improvements from 2026-02-14 audit#19
Peyton-Spencer merged 2 commits intomainfrom
fix/stability-quick-wins

Conversation

@Peyton-Spencer
Copy link
Copy Markdown

@Peyton-Spencer Peyton-Spencer commented Feb 14, 2026

Summary

Implements 4 critical stability fixes from comprehensive audit (2026-02-14).

Changes

  1. Unhandled Promise Rejection Handler (CRITICAL) - Prevents process crashes
  2. WhatsApp Event Listener Memory Leak (CRITICAL) - Fixes OOM on reconnect
  3. Group Folder Path Traversal (MEDIUM) - Security hardening
  4. Database Transaction Support (MEDIUM) - Prevents corrupted state

Files Changed

  • src/index.ts - Rejection handler + path validation
  • src/channels/whatsapp.ts - Event listener cleanup
  • src/db.ts - Transaction support + SQL safety docs

Audit Findings Addressed

Testing

  • Code review completed
  • Manual testing of WhatsApp reconnection
  • Path validation edge cases tested

Full audit report: nanoclaw-stability-audit-2026-02-14.md (25 issues identified)


Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com

Summary by CodeRabbit

  • Bug Fixes
    • Fixed potential memory leaks in messaging connections
    • Enhanced security validation for group folder handling
    • Improved transaction atomicity for task operations
    • Added robust error logging for system stability

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 14, 2026

📝 Walkthrough

Walkthrough

These changes enhance memory management, transaction safety, and security. The WhatsAppChannel now explicitly manages event handler lifecycle with cleanup on reconnects. Database operations gain atomic transaction wrapping. Input validation prevents path traversal attacks, and unhandled rejection logging improves error observability.

Changes

Cohort / File(s) Summary
WhatsApp Event Handler Lifecycle
src/channels/whatsapp.ts
Added private handler fields (messageHandler, reactionHandler, connectionHandler, credsHandler) and modified connectInternal to remove previously registered socket event listeners before re-registering, preventing memory leaks during reconnection cycles.
Database Transaction Safety
src/db.ts
deleteTask now wraps dual deletion operations in a transaction for atomicity; updateTask adds security documentation clarifying hardcoded field names and parameterized query usage.
Security and Error Handling
src/index.ts
registerGroup validates group.folder against regex to block invalid characters and verifies resolved path stays within groups root (path traversal prevention); main adds global unhandledRejection handler for critical error logging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Event handlers cleared like burrows swept clean,
Transactions now atomic, database serene,
Paths validated, rejections all caught,
Memory leaks vanquished—security bought! 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main purpose of the changeset—implementing critical stability improvements from a security audit. It is concise, clear, and specific enough for teammates to understand the primary change.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/stability-quick-wins

No actionable comments were generated in the recent review. 🎉


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @.github/workflows/upstream-sync.yml:
- Around line 23-55: The workflow uses hard-coded repo names (e.g., the git
remote add lines and gh api calls referencing qwibitai/nanoclaw and
cosmin/microclaw); change them to use reusable variables or workflow inputs (for
example inputs upstream_repo and microclaw_repo or env vars REPO_UPSTREAM and
REPO_MICROCLAW) and update the commands in the steps Add upstream remotes, Check
for new upstream PRs, Check for upstream issues in microclaw, and Create summary
to interpolate those variables instead of literal names; also ensure GH_TOKEN
remains set in the steps that call gh api and propagate the new variables into
the env for those steps so the commands (git remote add, git fetch, gh api)
continue to work.
- Around line 47-55: The workflow writes multiple lines to the same summary file
using repeated unquoted redirects which triggers SC2086/SC2129; update the run
step that appends to GITHUB_STEP_SUMMARY so all echo/gh outputs are grouped
inside a single brace group (e.g. { ... }) redirected once, and quote the
variable as "$GITHUB_STEP_SUMMARY" everywhere to avoid word-splitting; locate
the block that references GITHUB_STEP_SUMMARY and replace the repeated >>
$GITHUB_STEP_SUMMARY redirects with a single redirect of the grouped commands to
"$GITHUB_STEP_SUMMARY".

In `@scripts/upstream-tracker.sh`:
- Around line 7-31: The script currently hardcodes NANOCLAW_REPO, MICROCLAW_REPO
and FORK_REPO; change it so those identifiers are read from environment
variables or command-line args (e.g., use NANOCLAW_REPO, MICROCLAW_REPO,
FORK_REPO env vars with sensible defaults) and validate they are set before
performing git/gh calls; update references to these symbols (NANOCLAW_REPO,
MICROCLAW_REPO, FORK_REPO and any echo lines that embed them) to use the env/arg
values and exit with a clear error if required vars are missing.

In `@src/channels/whatsapp.ts`:
- Around line 44-45: The reaction handler is calling the async translateJid
without awaiting it, passing a Promise to onReaction; update the reaction
handler to await translateJid(...) (the same way messageHandler does) so
onReaction receives a resolved string, and ensure any surrounding code in the
reactionHandler handles async/await (e.g., mark the handler callback async or
await before calling this.reactionHandler). Reference: translateJid, onReaction,
reactionHandler.
🧹 Nitpick comments (1)
src/group-helpers.ts (1)

39-49: Prefer MAIN_GROUP_FOLDER instead of the 'main' literal.
Keeps the helper aligned if the configured main folder ever changes.

♻️ Proposed refactor
-import type { RegisteredGroup } from './types.js';
+import type { RegisteredGroup } from './types.js';
+import { MAIN_GROUP_FOLDER } from './config.js';
@@
-export function findMainGroupJid(registeredGroups: Record<string, RegisteredGroup>): string | undefined {
-  return Object.entries(registeredGroups).find(([, g]) => g.folder === 'main')?.[0];
+export function findMainGroupJid(registeredGroups: Record<string, RegisteredGroup>): string | undefined {
+  return Object.entries(registeredGroups).find(([, g]) => g.folder === MAIN_GROUP_FOLDER)?.[0];
 }
@@
 export function isMainGroup(folder: string): boolean {
-  return folder === 'main';
+  return folder === MAIN_GROUP_FOLDER;
 }

Comment thread .github/workflows/upstream-sync.yml Outdated
Comment thread .github/workflows/upstream-sync.yml Outdated
Comment thread scripts/upstream-tracker.sh Outdated
Comment on lines +7 to +31
NANOCLAW_REPO="qwibitai/nanoclaw"
MICROCLAW_REPO="cosmin/microclaw"
FORK_REPO="omniaura/nanoclaw"

echo "🔍 Fetching upstream changes..."
git fetch upstream --quiet || echo "⚠️ Failed to fetch from upstream"
git fetch microclaw --quiet || echo "⚠️ Failed to fetch from microclaw"

echo ""
echo "📋 Recent Upstream PRs (qwibitai/nanoclaw):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

gh api "repos/${NANOCLAW_REPO}/pulls" --jq '.[] | select(.state=="open") | "#\(.number) - \(.title)\n Created: \(.created_at) | Comments: \(.comments)"' | head -30

echo ""
echo "📋 Recent MicroClaw Issues (cosmin/microclaw):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

gh api "repos/${MICROCLAW_REPO}/issues" --jq '.[] | select(.state=="open" and (.title | contains("Upstream"))) | "#\(.number) - \(.title)\n Created: \(.created_at) | Comments: \(.comments)"' | head -20

echo ""
echo "✅ Upstream tracking complete!"
echo ""
echo "💡 To create a tracking issue on ${FORK_REPO}:"
echo " gh issue create --title \"[Upstream PR #X] Feature name\" --body \"Link: https://github.com/${NANOCLAW_REPO}/pull/X\""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid hard-coded repo identifiers in source.
These org/repo values are user-specific; please externalize them (env/args) so the script remains generic and compliant.

🔧 Proposed fix (read from env)
-NANOCLAW_REPO="qwibitai/nanoclaw"
-MICROCLAW_REPO="cosmin/microclaw"
-FORK_REPO="omniaura/nanoclaw"
+NANOCLAW_REPO="${NANOCLAW_REPO:?Set NANOCLAW_REPO (owner/repo)}"
+MICROCLAW_REPO="${MICROCLAW_REPO:?Set MICROCLAW_REPO (owner/repo)}"
+FORK_REPO="${FORK_REPO:?Set FORK_REPO (owner/repo)}"

As per coding guidelines: "NEVER edit checked-in templates or source files with user-specific content like project names, directory paths, personal preferences, or org-specific details".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
NANOCLAW_REPO="qwibitai/nanoclaw"
MICROCLAW_REPO="cosmin/microclaw"
FORK_REPO="omniaura/nanoclaw"
echo "🔍 Fetching upstream changes..."
git fetch upstream --quiet || echo "⚠️ Failed to fetch from upstream"
git fetch microclaw --quiet || echo "⚠️ Failed to fetch from microclaw"
echo ""
echo "📋 Recent Upstream PRs (qwibitai/nanoclaw):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
gh api "repos/${NANOCLAW_REPO}/pulls" --jq '.[] | select(.state=="open") | "#\(.number) - \(.title)\n Created: \(.created_at) | Comments: \(.comments)"' | head -30
echo ""
echo "📋 Recent MicroClaw Issues (cosmin/microclaw):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
gh api "repos/${MICROCLAW_REPO}/issues" --jq '.[] | select(.state=="open" and (.title | contains("Upstream"))) | "#\(.number) - \(.title)\n Created: \(.created_at) | Comments: \(.comments)"' | head -20
echo ""
echo "✅ Upstream tracking complete!"
echo ""
echo "💡 To create a tracking issue on ${FORK_REPO}:"
echo " gh issue create --title \"[Upstream PR #X] Feature name\" --body \"Link: https://github.com/${NANOCLAW_REPO}/pull/X\""
NANOCLAW_REPO="${NANOCLAW_REPO:?Set NANOCLAW_REPO (owner/repo)}"
MICROCLAW_REPO="${MICROCLAW_REPO:?Set MICROCLAW_REPO (owner/repo)}"
FORK_REPO="${FORK_REPO:?Set FORK_REPO (owner/repo)}"
echo "🔍 Fetching upstream changes..."
git fetch upstream --quiet || echo "⚠️ Failed to fetch from upstream"
git fetch microclaw --quiet || echo "⚠️ Failed to fetch from microclaw"
echo ""
echo "📋 Recent Upstream PRs (qwibitai/nanoclaw):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
gh api "repos/${NANOCLAW_REPO}/pulls" --jq '.[] | select(.state=="open") | "#\(.number) - \(.title)\n Created: \(.created_at) | Comments: \(.comments)"' | head -30
echo ""
echo "📋 Recent MicroClaw Issues (cosmin/microclaw):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
gh api "repos/${MICROCLAW_REPO}/issues" --jq '.[] | select(.state=="open" and (.title | contains("Upstream"))) | "#\(.number) - \(.title)\n Created: \(.created_at) | Comments: \(.comments)"' | head -20
echo ""
echo "✅ Upstream tracking complete!"
echo ""
echo "💡 To create a tracking issue on ${FORK_REPO}:"
echo " gh issue create --title \"[Upstream PR `#X`] Feature name\" --body \"Link: https://github.com/${NANOCLAW_REPO}/pull/X\""
🤖 Prompt for AI Agents
In `@scripts/upstream-tracker.sh` around lines 7 - 31, The script currently
hardcodes NANOCLAW_REPO, MICROCLAW_REPO and FORK_REPO; change it so those
identifiers are read from environment variables or command-line args (e.g., use
NANOCLAW_REPO, MICROCLAW_REPO, FORK_REPO env vars with sensible defaults) and
validate they are set before performing git/gh calls; update references to these
symbols (NANOCLAW_REPO, MICROCLAW_REPO, FORK_REPO and any echo lines that embed
them) to use the env/arg values and exit with a clear error if required vars are
missing.

Comment thread src/channels/whatsapp.ts Outdated
Copy link
Copy Markdown

@nicktallen nicktallen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Approved - Critical stability fixes

Addresses 4 critical issues from stability audit.

CRITICAL Fixes:

  1. Unhandled promise rejection handler - prevents process crashes
  2. WhatsApp event listener memory leak - fixes OOM on reconnect
  3. Path traversal validation - security hardening
  4. Database transactions - prevents corrupted state

Code Quality:
• Proper event handler cleanup in WhatsApp channel
• Input validation for group folder names
• Path traversal detection with safety checks
• Transaction support for atomic DB operations
• Helper utilities for group resolution (DRY)

Impact:
• Prevents production crashes from unhandled rejections
• Fixes memory leak that causes OOM
• Hardens security against path traversal attacks
• Prevents race conditions in DB updates

These are important production stability improvements. The implementation is solid - proper cleanup, validation, and error handling throughout. Ready to merge.

Copy link
Copy Markdown

@omarzanji omarzanji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good critical fixes, but this PR contains commits from PR #16 (group-helpers.ts, upstream-sync.yml). Please rebase on main after PR #16 is merged to remove duplicate commits. The stability fixes themselves (unhandled rejection handler, WhatsApp memory leak, path traversal validation, DB transactions) are all excellent and critical.

@Peyton-Spencer Peyton-Spencer force-pushed the fix/stability-quick-wins branch from 10cc998 to 6fbde45 Compare February 14, 2026 05:35
nanoclaw and others added 2 commits February 14, 2026 00:38
Implements three critical stability fixes identified in the audit:

1. **Unhandled Promise Rejection Handler (CRITICAL)**
   - Add process.on('unhandledRejection') to prevent crashes
   - Logs rejections instead of exiting to maintain service uptime
   - Prevents complete service outage from uncaught promise errors

2. **WhatsApp Event Listener Memory Leak (CRITICAL)**
   - Store event handlers and remove them before reconnection
   - Prevents exponential handler accumulation on reconnects
   - Fixes memory leak leading to eventual OOM crashes

3. **Group Folder Path Traversal (MEDIUM)**
   - Validate folder names with regex (alphanumeric + _ -)
   - Verify resolved paths stay within groups directory
   - Prevents malicious group registration from writing to arbitrary paths

Impact:
- Prevents process crashes from unhandled rejections
- Fixes production memory leak in WhatsApp channel
- Hardens security against path traversal attacks

Related:
- Audit report: nanoclaw-stability-audit-2026-02-14.md
- Issues #1, #4, #16 from stability audit

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…omment

Database improvements from stability audit:

1. **Transaction Support for deleteTask (MEDIUM)**
   - Wrap DELETE operations in explicit transaction
   - Ensures both child and parent deletions succeed atomically
   - Prevents partial deletion leaving orphaned task_run_logs

2. **SQL Injection Safety Documentation (HIGH)**
   - Add security comment to updateTask explaining safety assumptions
   - Document that field names are hardcoded (not user-controlled)
   - Warn future maintainers about SQL injection risks if logic changes

Impact:
- Prevents database corruption from partial task deletions
- Documents security assumptions for future code reviewers
- Hardens codebase against accidental SQL injection introduction

Related:
- Audit report: nanoclaw-stability-audit-2026-02-14.md
- Issues #3, #12 from stability audit

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants