stamparm/maltrail · error · SystemExit
[!] no version key found in
Error message
[!] no version key found in %s
What it means
check_version.py extracts the version from CITATION.cff with a regex over a 'version:' key. If the file exists but has no version key (or it's formatted unusually, e.g. unquoted or different indentation/spacing), the regex fails and the tool exits with this message rather than silently returning a wrong version. This guards the release pipeline from citing the wrong paper version.
Solutions
- Open CITATION.cff and add/restore a top-level version key: version: "3.2"
- Check the key uses 'version:' with regular spaces before the value and the value is quoted
- Run check_version.py again to confirm all version sources agree
- Validate the file with a CFF validator (cffconvert) to catch other schema issues
Example fix
// before (CITATION.cff missing key) # CITATION.cff authors: - ... // after authors: - ... version: "3.2"
Defensive patterns
Strategy: validation
Validate before calling
import re, pathlib
text = pathlib.Path("CITATION.cff").read_text()
assert re.search(r'^version\s*:\s*["\'][^"\']+["\']', text, re.M), "CITATION.cff missing version key" Prevention
- Keep version as the last line you never touch during manual edits
- Validate CITATION.cff with cffconvert in CI
- Never resolve merge conflicts by deleting the version key
When it happens
Trigger: Running check_version.py (via main) when sensor/../CITATION.cff lacks a line matching ^version: "..." — e.g. the key was renamed, removed, uses no quotes, or uses tabs instead of spaces after the colon.
Common situations: Hand-editing CITATION.cff during a release and accidentally dropping or reformatting the version key; a merge conflict resolved by deleting the key; committing a template CITATION.cff with placeholders.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- [!] no VERSION constant found in
- [!] no maltrail-sensor package entry found in
- [x] invalid IP address
- not a Maltrail provenance sidecar (bad magic)
- provenance sidecar is truncated
AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13).
Data as JSON: /api/errors/636881f847b3a382.
Report an issue: GitHub.
Appendix: source
Thrown at sensor/tools/check_version.py:70
if not package:
raise SystemExit("[!] no [package] table found in %s" % CARGO)
match = re.search(r"^version\s*=\s*\"([^\"]+)\"", package.group(1), re.M)
if not match:
raise SystemExit("[!] no version key in the [package] table of %s" % CARGO)
return match.group(1)
def citation_version():
"""version: "3.0" from CITATION.cff.
Nothing linked this to the tree, and it drifted: the file still claimed 3.0 while the code,
the sensor and the published tag were all 3.1.1. That is not cosmetic - CITATION.cff exists
so a paper can cite a specific version, and it had been quietly citing the wrong one.
"""
match = re.search(r"^version\s*:\s*[\"']([^\"']+)[\"']", _read(CITATION), re.M)
if not match:
raise SystemExit("[!] no version key found in %s" % CITATION)
return match.group(1)
def settings_gen_version():
"""pub const VERSION: &str = "3.2"; from the generated mirror of core/settings.py.
This is a FOURTH place the version lives, and it was the one nobody checked here. The Rust
parity test covers it, but that test needs a Rust toolchain - so the automated monthly bump,
which is a text edit on a machine that has none, could not tell it had gone stale. It found
out from a failed release: the tag was already pushed, the gate refused it, and nothing was
built. A version bump is text; verifying it should be text too.
"""
match = re.search(r'^pub const VERSION: &str = "([^"]+)";', _read(SETTINGS_GEN), re.M)
if not match:
raise SystemExit("[!] no VERSION constant found in %s" % SETTINGS_GEN)
return match.group(1)
View on GitHub (pinned to 77cfb06d76)