Summary
While evaluating the skill catalog, I executed every skills/*/scripts/agent.py (809 scripts) once via subprocess on Python 3.14 (Linux/WSL2, Ubuntu) and again on Python 3.12 (Windows). Most scripts behave as expected (run on built-in demo data, or exit cleanly asking for an input artifact / API key). This report collects 5 genuine, reproducible runtime defects — code bugs independent of missing dependencies, missing input, or missing credentials.
Two of them (#1, #2) fail at module import, so the affected skill cannot start at all.
I verified each on Linux with the relevant libraries installed, so these are not "missing dependency" artifacts. Happy to open a PR if useful.
| # |
Skill |
File:Line |
Error |
When |
| 1 |
configuring-snort-ids-for-intrusion-detection |
scripts/agent.py:17 |
NameError: name 'DAQ_DIR' is not defined |
import time (always) |
| 2 |
deploying-ransomware-canary-files |
scripts/agent.py:281 |
NameError: name 'FileSystemEventHandler' is not defined |
import time, when watchdog not installed |
| 3 |
analyzing-linux-elf-malware |
scripts/agent.py:127-129 |
ValueError: stdout and stderr arguments may not be used with capture_output |
whenever a target is analyzed |
| 4 |
monitoring-darkweb-sources |
scripts/agent.py:149 |
KeyError: 'name' |
default run (no HIBP API key) |
| 5 |
performing-log-analysis-for-forensic-investigation |
scripts/agent.py:191/194 |
ValueError: dict contains fields not in fieldnames: 'service', 'host', 'message' |
when parsing syslog + another source together |
1. configuring-snort-ids — self-referential default (NameError at import)
# line 13-17
SNORT_BIN = os.environ.get("SNORT_BIN", "/usr/local/bin/snort")
SNORT_CONF = os.environ.get("SNORT_CONF", "/usr/local/etc/snort/snort.lua")
RULES_DIR = os.environ.get("SNORT_RULES_DIR", "/usr/local/etc/snort/rules")
LOG_DIR = os.environ.get("SNORT_LOG_DIR", "/var/log/snort")
DAQ_DIR = os.environ.get("SNORT_DAQ_DIR", DAQ_DIR) # <-- DAQ_DIR used as its own default
DAQ_DIR is referenced as its own fallback before it exists. The other four vars use a literal default; this one was likely a copy/paste miss.
Fix: give it a literal default like the others, e.g.
DAQ_DIR = os.environ.get("SNORT_DAQ_DIR", "/usr/local/lib/daq")
2. deploying-ransomware-canary-files — unguarded class base (NameError at import)
# line 22-24
try:
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
except ImportError:
... # import guarded
...
# line 281 (module scope)
class CanaryFileHandler(FileSystemEventHandler): # <-- base undefined if watchdog missing
The import is guarded, but the class inherits FileSystemEventHandler at module scope, so when watchdog is absent the module raises NameError at load — before any friendly "pip install watchdog" message can print.
Fix: guard the class (or the whole watchdog-dependent block), e.g.
_Base = FileSystemEventHandler if HAS_WATCHDOG else object
class CanaryFileHandler(_Base):
...
or declare watchdog a hard requirement and fail with a clear message.
3. analyzing-linux-elf-malware — invalid subprocess.run args (ValueError on every analysis)
# check_packing(), line 127-129
stdout, _, _ = subprocess.run(["upx", "-t", filepath],
capture_output=True, text=True,
stderr=subprocess.STDOUT, timeout=120).stdout, "", 0
subprocess.run rejects stderr= together with capture_output=True. This raises unconditionally as soon as check_packing() runs (i.e. any real ELF target), before UPX is even invoked.
Fix: drop stderr=subprocess.STDOUT (capture_output already captures stderr):
proc = subprocess.run(["upx", "-t", filepath], capture_output=True, text=True, timeout=120)
stdout = proc.stdout
4. monitoring-darkweb-sources — hard key access on optional field (KeyError)
# line 149
lines.append(f" - {b['name']} ({b['breach_date']}) - {b['pwn_count']:,} accounts")
On the default run (no HIBP API key), the breach records passed to the report do not carry a name key, so this crashes. Note lines 43-44 already use .get(...) defensively for the same records.
Fix: be consistent and defensive:
lines.append(f" - {b.get('name','Unknown')} ({b.get('breach_date','?')}) - {b.get('pwn_count',0):,} accounts")
5. performing-log-analysis-for-forensic-investigation — CSV fieldnames from first row only (ValueError)
# line 191
writer = csv.DictWriter(f, fieldnames=list(timeline[0].keys()))
writer.writeheader()
for event in timeline:
# line 194
writer.writerow({k: str(v)[:200] for k, v in event.items()})
fieldnames is derived from timeline[0] only. When the timeline mixes event types (e.g. syslog entries add service, host, message that the first event lacks), writerow raises. Reproduced by passing both a syslog and another source.
Fix: compute the union of keys, or ignore extras:
fieldnames = sorted({k for e in timeline for k in e})
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")
Reproduction
python3 skills/configuring-snort-ids-for-intrusion-detection/scripts/agent.py # NameError at import
python3 skills/deploying-ransomware-canary-files/scripts/agent.py # NameError at import (no watchdog)
python3 skills/analyzing-linux-elf-malware/scripts/agent.py /bin/ls # ValueError in check_packing
python3 skills/monitoring-darkweb-sources/scripts/agent.py # KeyError: 'name'
Environment: Python 3.14.4 (Ubuntu/WSL2) and Python 3.12 (Windows); libraries pyelftools, scapy, pefile, boto3, requests, watchdog(absent for #2) as relevant.
Summary
While evaluating the skill catalog, I executed every
skills/*/scripts/agent.py(809 scripts) once viasubprocesson Python 3.14 (Linux/WSL2, Ubuntu) and again on Python 3.12 (Windows). Most scripts behave as expected (run on built-in demo data, or exit cleanly asking for an input artifact / API key). This report collects 5 genuine, reproducible runtime defects — code bugs independent of missing dependencies, missing input, or missing credentials.Two of them (#1, #2) fail at module import, so the affected skill cannot start at all.
I verified each on Linux with the relevant libraries installed, so these are not "missing dependency" artifacts. Happy to open a PR if useful.
configuring-snort-ids-for-intrusion-detectionscripts/agent.py:17NameError: name 'DAQ_DIR' is not defineddeploying-ransomware-canary-filesscripts/agent.py:281NameError: name 'FileSystemEventHandler' is not definedwatchdognot installedanalyzing-linux-elf-malwarescripts/agent.py:127-129ValueError: stdout and stderr arguments may not be used with capture_outputmonitoring-darkweb-sourcesscripts/agent.py:149KeyError: 'name'performing-log-analysis-for-forensic-investigationscripts/agent.py:191/194ValueError: dict contains fields not in fieldnames: 'service', 'host', 'message'1.
configuring-snort-ids— self-referential default (NameError at import)DAQ_DIRis referenced as its own fallback before it exists. The other four vars use a literal default; this one was likely a copy/paste miss.Fix: give it a literal default like the others, e.g.
2.
deploying-ransomware-canary-files— unguarded class base (NameError at import)The import is guarded, but the class inherits
FileSystemEventHandlerat module scope, so whenwatchdogis absent the module raisesNameErrorat load — before any friendly "pip install watchdog" message can print.Fix: guard the class (or the whole watchdog-dependent block), e.g.
or declare
watchdoga hard requirement and fail with a clear message.3.
analyzing-linux-elf-malware— invalidsubprocess.runargs (ValueError on every analysis)subprocess.runrejectsstderr=together withcapture_output=True. This raises unconditionally as soon ascheck_packing()runs (i.e. any real ELF target), before UPX is even invoked.Fix: drop
stderr=subprocess.STDOUT(capture_output already captures stderr):4.
monitoring-darkweb-sources— hard key access on optional field (KeyError)On the default run (no HIBP API key), the breach records passed to the report do not carry a
namekey, so this crashes. Note lines 43-44 already use.get(...)defensively for the same records.Fix: be consistent and defensive:
5.
performing-log-analysis-for-forensic-investigation— CSV fieldnames from first row only (ValueError)fieldnamesis derived fromtimeline[0]only. When the timeline mixes event types (e.g. syslog entries addservice,host,messagethat the first event lacks),writerowraises. Reproduced by passing both a syslog and another source.Fix: compute the union of keys, or ignore extras:
Reproduction
Environment: Python 3.14.4 (Ubuntu/WSL2) and Python 3.12 (Windows); libraries
pyelftools,scapy,pefile,boto3,requests,watchdog(absent for #2) as relevant.