Skip to content

Troubleshooting

Stephen Cox edited this page Dec 10, 2025 · 3 revisions

Common Issues

Issue: "Connection refused" to qBittorrent

Symptoms:

ConnectionError: Failed to connect to qBittorrent at http://localhost:8080

Solutions:

  1. Check qBittorrent Web UI is running:

    • Open http://localhost:8080 in browser
    • If not accessible, enable Web UI in qBittorrent settings
  2. Verify host/port in config:

    qbittorrent:
      host: http://localhost:8080  # Match your qBittorrent Web UI
  3. Check firewall rules:

    # Linux: Allow port 8080
    sudo ufw allow 8080
  4. For remote qBittorrent, use full URL:

    qbittorrent:
      host: http://192.168.1.100:8080

Issue: Rules not matching expected torrents

Symptoms:

  • Rule conditions look correct but torrents aren't matched
  • No actions applied when they should be

Debugging steps:

  1. Enable trace mode:

    python triggers/manual.py --trace
  2. Check condition evaluation:

    [TRACE] Rule: "Remove old torrents"
    [TRACE]   Condition: info.ratio >= 2.0
    [TRACE]   Result: False (actual: 1.5)
    [TRACE]   Rule skipped
    
  3. Verify field values:

    # Check actual field values
    curl -X GET "http://localhost:8080/api/v2/torrents/info" \
      --cookie "SID=your_session_id"
  4. Common mistakes:

    • Wrong field name (info.name not info.torrent_name)
    • Wrong operator (== for exact match, contains for substring)
    • Wrong value type (string "1.0" vs float 1.0)
    • Collection fields not understood (see §10.3)

Issue: Actions not being applied

Symptoms:

  • Conditions match but actions don't execute
  • Logs show "skipping" messages

Possible causes:

  1. Dry-run mode enabled:

    # Remove --dry-run to apply changes
    python triggers/manual.py  # Not --dry-run
  2. Idempotent action already applied:

    [INFO] Torrent already stopped, skipping
    [INFO] Category already set to 'Movies', skipping
    

    This is normal behavior - action was already applied previously.

  3. Earlier rule matched with stop_on_match: true:

    - name: "First rule"
      stop_on_match: true  # Prevents later rules from running
  4. Invalid action parameters:

    [ERROR] Invalid category name: 'Invalid/Category'
    

    Check parameter validation in logs.

Issue: Regex patterns not matching

Symptoms:

  • matches operator not finding expected torrents
  • Pattern works in regex tester but not in rules

Solutions:

  1. Use raw strings in YAML:

    # Wrong: Backslashes interpreted by YAML
    value: '\d+'
    
    # Right: Single quotes preserve backslashes
    value: '(?i).*\d+.*'
  2. Test regex patterns:

    import re
    pattern = r'(?i).*[Ss]\d{2}[Ee]\d{2}.*'
    test_string = "Show.Name.S01E05.1080p"
    print(re.match(pattern, test_string))  # Should match
  3. Use (?i) for case-insensitive:

    - field: info.name
      operator: matches
      value: '(?i).*sample.*'  # Matches "Sample", "SAMPLE", "sample"
  4. Escape special characters:

    # To match literal dots
    value: '.*\.mkv$'  # Matches ".mkv" extension

Debugging Commands

Check qBittorrent API access

# Test authentication
curl -X POST "http://localhost:8080/api/v2/auth/login" \
  -d "username=admin&password=your_password"

# Get torrent list
curl -X GET "http://localhost:8080/api/v2/torrents/info" \
  --cookie "SID=your_session_id"

# Get specific torrent details
curl -X GET "http://localhost:8080/api/v2/torrents/properties?hash=TORRENT_HASH" \
  --cookie "SID=your_session_id"

Test config file syntax

# Validate YAML syntax
python -c "import yaml; yaml.safe_load(open('config/config.yml'))"
python -c "import yaml; yaml.safe_load(open('config/rules.yml'))"

Test module imports

# Verify all modules load correctly
python -c "from lib.api import QBittorrentAPI; print('✓ API')"
python -c "from lib.config import load_config; print('✓ Config')"
python -c "from lib.engine import RulesEngine; print('✓ Engine')"

Run with maximum verbosity

# Enable all logging
python triggers/manual.py --trace --dry-run

Check Python environment

# Verify Python version (3.8+ required)
python --version

# Check dependencies
pip list | grep -E '(requests|pyyaml)'

Log Analysis

Understanding log levels

[DEBUG]  # Development information (not shown by default)
[INFO]   # Normal operation messages
[WARNING]  # Potential issues that don't stop execution
[ERROR]  # Errors that prevent specific actions
[TRACE]  # Detailed execution flow (--trace flag required)

Common log messages

Normal operation:

[INFO] Loaded 5 rules from config/rules.yml
[INFO] Processing 42 torrents
[INFO] Rule "Remove old torrents" matched torrent "Example.Torrent"
[INFO] Executing action: delete_torrent
[INFO] Deleted torrent: Example.Torrent (hash: abc123...)

Idempotent skips (normal):

[INFO] Torrent already stopped, skipping
[INFO] Category already set to 'Movies', skipping
[INFO] Tag 'auto' already exists, skipping

Errors:

[ERROR] Failed to delete torrent abc123: 404 Torrent not found
[ERROR] Invalid category name: 'Invalid/Category'
[ERROR] Connection timeout after 30s

Trace mode (debugging):

[TRACE] Fetching trackers for torrent: abc123
[TRACE] API call: /api/v2/torrents/trackers?hash=abc123
[TRACE] Response: [{'url': 'udp://tracker.example.com:80', ...}]
[TRACE] Evaluating condition: trackers.url contains "example.com"
[TRACE] Result: True

Performance Issues

Slow execution with many torrents

Symptoms:

  • Rules take minutes to run
  • High API call volume

Solutions:

  1. Add filters to reduce torrent set:

    conditions:
      filter:
        category: "Movies"  # Only process specific category
        state: "downloading"  # Only active torrents
  2. Avoid expensive fields:

    # Fast: Uses cached info.* data
    - field: info.ratio
      operator: ">="
      value: 2.0
    
    # Slow: Requires API call per torrent
    - field: files.name
      operator: contains
      value: "sample"
  3. Use stop_on_match:

    - name: "First match wins"
      stop_on_match: true  # Don't evaluate remaining rules
  4. Run less frequently:

    # Cron: Every 6 hours instead of hourly
    0 */6 * * * python triggers/scheduled.py

High memory usage

Symptoms:

  • Python process using excessive RAM
  • Out of memory errors

Solutions:

  1. Process torrents in batches (requires code modification)
  2. Reduce concurrent API calls
  3. Clear caches more frequently

🎯 qbt-rules

v0.3.0 | GitHub


📚 Getting Started

📖 Core Concepts

🔧 Configuration

🆘 Help & Support

🤝 Contributing


🆕 What's New (v0.3.0)

  • ✅ Unified CLI (qbt-rules)
  • ✅ Custom triggers
  • ✅ Trigger-agnostic mode
  • ✅ Size operators (50GB)

🔗 Quick Links

Clone this wiki locally