ruvnet/RuView · error · ValueError
Insufficient data for CSI
Error message
Insufficient data for CSI
What it means
ValueError from parse_csi_data when the buffer is shorter than HEADER_SIZE + header['csi_length'], i.e. the header parsed fine and declares a CSI payload size that the remaining bytes do not cover. The guard protects the slice data[csi_start:csi_start + csi_length] and the 10-bit unpack loop that follows.
Source
Thrown at plans/phase2-architecture/hardware-integration.md:375
return {
'timestamp': header[0],
'channel': header[1],
'rate': header[2],
'rssi': header[3] - 256 if header[3] > 127 else header[3],
'noise': header[4] - 256 if header[4] > 127 else header[4],
'antenna_config': header[5],
'csi_length': header[6],
'mac_address': header[7]
}
@staticmethod
def parse_csi_data(data, header):
"""Parse CSI complex values"""
csi_start = AtherosCSIFormat.HEADER_SIZE
csi_length = header['csi_length']
if len(data) < csi_start + csi_length:
raise ValueError("Insufficient data for CSI")
# Atheros format: 10-bit values packed
# [real_0|imag_0|real_1|imag_1|...]
csi_raw = data[csi_start:csi_start + csi_length]
# Unpack 10-bit values
num_values = csi_length * 8 // 10
csi_complex = np.zeros(num_values // 2, dtype=complex)
bit_offset = 0
for i in range(0, num_values, 2):
# Extract 10-bit real and imaginary parts
real = AtherosCSIFormat._extract_10bit(csi_raw, bit_offset)
imag = AtherosCSIFormat._extract_10bit(csi_raw, bit_offset + 10)
# Convert to signed values
real = real - 512 if real > 511 else real
imag = imag - 512 if imag > 511 else imagView on GitHub (pinned to 4685618388)
Solutions
- Accumulate data until len(data) >= HEADER_SIZE + header['csi_length'] before calling parse_csi_data
- Sanity-check header['csi_length'] (0 < csi_length <= max expected for the antenna config / channel width) and discard the packet as corrupt if it fails
- If lengths are consistently wrong after a firmware update, update the parser's expected layout
- Treat this as a drop-and-continue error in the capture loop; log the declared vs available lengths for diagnosis
Example fix
# before
csi = AtherosCSIFormat.parse_csi_data(buf, header) # ValueError when payload truncated
# after
need = AtherosCSIFormat.HEADER_SIZE + header['csi_length']
if len(buf) < need:
buf += read_more()
csi = AtherosCSIFormat.parse_csi_data(buf, header) Defensive patterns
Strategy: validation
Validate before calling
need = AtherosCSIFormat.HEADER_SIZE + header['csi_length']
if len(buf) < need:
buf += read_more()
if not (0 < header['csi_length'] <= MAX_EXPECTED_CSI_LEN):
drop_packet() # corrupt header; parsing would fail or yield garbage Type guard
def has_full_csi(buf: bytes, header: dict) -> bool:
return len(buf) >= AtherosCSIFormat.HEADER_SIZE + header['csi_length'] Try / catch
try:
csi = AtherosCSIFormat.parse_csi_data(buf, header)
except ValueError as e:
if 'Insufficient data for CSI' in str(e):
logging.warning('truncated CSI: declared %d, have %d', header['csi_length'], len(buf))
continue # drop, stay in sync via framing
raise Prevention
- Header and CSI must come from the same accumulated buffer, not separate reads
- Bound csi_length with a plausibility check before trusting it
- After firmware changes, re-validate expected CSI payload sizes for the new build
When it happens
Trigger: Calling parse_csi_data with only the header bytes; a truncated capture where csi_length bytes were not yet read; a corrupted csi_length field (e.g. bit-flip) making the declared payload larger than the actual packet; off-by-N desync after a dropped packet.
Common situations: Splitting header parsing and CSI parsing across two reads without accumulating; firmware/driver version changing the CSI payload size while the parser assumes the old layout; noisy RF captures occasionally producing garbage headers.
Related errors
- Insufficient data for header
- Packet too small
- Invalid axis token {token!r}; expected one of {sorted(_AXIS_
- Unsupported router type: {router_type}
- Page must be >= 1
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/05f8bc140c0dad24.
Report an issue: GitHub.