stamparm/maltrail · error
unsupported type
Error message
unsupported type '%s'
What it means
Validation guard in TrailsDict.__setitem__: the value assigned to a key must be a tuple or list (a trail of hop pairs); any other type — a plain string, int, dict, None, etc. — is rejected. This is a sentinel-style generic Exception used to enforce the container's value contract before the value is normalized into the internal pair/value storage. Fix by passing the trail as a tuple/list of pairs, e.g. td[key] = (('1.2.3.4', '5.6.7.8'), ...), or by wrapping scalars in the structure the API expects.
Solutions
- Wrap the value in a tuple, e.g. trails[key] = (interval, "malware")
- Ensure loaders convert each row to a tuple/list before assignment
- Add an isinstance check on values before writing
- Catch Exception in the update loop and log the offending type
Example fix
// before
trails[key] = value # value is a str from CSV
// after
interval, name = value.split(",")
trails[key] = (int(interval), name) Defensive patterns
Strategy: type-guard
Validate before calling
def trails_value_ok(value):
return isinstance(value, (tuple, list)) and len(value) >= 2 Type guard
def is_trail_pair(value):
return isinstance(value, (tuple, list)) and len(value) >= 2 Try / catch
try:
trails[key] = value
except Exception as e:
if "unsupported type" in str(e):
trails[key] = tuple(value) if isinstance(value, (list, tuple)) else (value, "") Prevention
- Always assign 2-element (interval, type) tuples
- Coerce loader output (CSV/JSON strings) into tuples before assignment
- Add a helper setter that validates the pair shape
- Cover value-type contract in unit tests
When it happens
Trigger: trails[key] = "some string"; assigning None, an int, or a dict; passing a generator/iterator instead of a materialized pair; refactoring changed value shape from tuple to custom object.
Common situations: Typos or refactors in update scripts, JSON/CSV loaders yielding strings, code adapted from a different trails structure.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- [x] invalid IP address
- not a Maltrail provenance sidecar (bad magic)
- provenance sidecar is truncated
- packet too short for header-protection sample
- trail bin too small
AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13).
Data as JSON: /api/errors/5b0fdd5bf1c29e12.
Report an issue: GitHub.
Appendix: source
Thrown at core/trailsdict.py:272
return pair_list[values[i]]
i += 1
return default
def __len__(self):
mm = self._mmap
if mm is not None:
return mm["length"]
frozen = self._frozen
return frozen[5] if frozen is not None else len(self._trails)
def clear(self):
self.__init__()
def __setitem__(self, key, value):
if self._frozen is not None or self._mmap is not None:
raise Exception("cannot modify a finalized TrailsDict")
if not isinstance(value, (tuple, list)):
raise Exception("unsupported type '%s'" % type(value))
pair = (value[0], value[1])
shared = self._pairs.get(pair)
if shared is None:
shared = pair
self._pairs[pair] = pair
self._trails[key] = shared
def __delitem__(self, key):
if self._frozen is not None or self._mmap is not None:
raise Exception("cannot modify a finalized TrailsDict")
del self._trails[key]
def update(self, value):
if self._frozen is not None or self._mmap is not None:
raise Exception("cannot modify a finalized TrailsDict")
if isinstance(value, (TrailsDict, dict)):
for key in value:View on GitHub (pinned to 77cfb06d76)