ruvnet/RuView · error · CSIExtractionError

ESP32 CSI data contains non-numeric values: {ve}. Raw CSI fi

Error message

ESP32 CSI data contains non-numeric values: {ve}. Raw CSI fields must be numeric float values.

What it means

CSIExtractionError raised when float() fails on any of the first expected_values CSV fields: the CSI payload contains non-numeric tokens. Header parsing already succeeded, so this is strictly about the amplitude/phase values — empty strings from consecutive/trailing commas, placeholder words, or mojibake that survived the header check.

Source

Thrown at archive/v1/src/hardware/csi_extractor.py:108

            # Parse amplitude and phase arrays from the remaining CSV fields.
            # Expected format after the header fields: comma-separated float values
            # representing interleaved amplitude and phase per antenna per subcarrier.
            data_values = parts[6:]
            expected_values = num_antennas * num_subcarriers * 2  # amplitude + phase

            if len(data_values) < expected_values:
                raise CSIExtractionError(
                    f"ESP32 CSI data incomplete: expected {expected_values} values "
                    f"(amplitude + phase for {num_antennas} antennas x {num_subcarriers} subcarriers), "
                    f"but received {len(data_values)} values. "
                    "Ensure the ESP32 firmware is configured to output full CSI matrix data. "
                    "See docs/hardware-setup.md for ESP32 CSI configuration."
                )

            try:
                float_values = [float(v) for v in data_values[:expected_values]]
            except ValueError as ve:
                raise CSIExtractionError(
                    f"ESP32 CSI data contains non-numeric values: {ve}. "
                    "Raw CSI fields must be numeric float values."
                )

            all_values = np.array(float_values)
            amplitude = all_values[:num_antennas * num_subcarriers].reshape(num_antennas, num_subcarriers)
            phase = all_values[num_antennas * num_subcarriers:].reshape(num_antennas, num_subcarriers)
            
            return CSIData(
                timestamp=datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc),
                amplitude=amplitude,
                phase=phase,
                frequency=frequency,
                bandwidth=bandwidth,
                num_subcarriers=num_subcarriers,
                num_antennas=num_antennas,
                snr=snr,
                metadata={'source': 'esp32', 'raw_length': len(raw_data)}

View on GitHub (pinned to 4685618388)

Solutions

  1. Log and inspect the exact failing line; fix the firmware to emit plain decimal floats only in the CSI section
  2. Pre-validate each CSI field against a numeric regex before calling parse (see validationCode)
  3. For offline tests, generate lines with the same formatter the firmware uses instead of hand-writing them
Defensive patterns

Strategy: validation

Validate before calling

import re

NUMERIC = re.compile(r'-?[0-9]+(?:[eE][-+]?[0-9]+)?|-?[0-9]*[.][0-9]+(?:[eE][-+]?[0-9]+)?')

def csi_fields_numeric(line: str) -> bool:
    fields = line.strip().split(',')[6:]
    return bool(fields) and all(NUMERIC.fullmatch(f.strip()) for f in fields)

Try / catch

try:
    data = parser.parse(raw)
except CSIExtractionError as e:
    logger.warning('non-numeric CSI payload, dropping frame: %s', e)

Prevention

When it happens

Trigger: A line like 'CSI_DATA:...,1,2,3,,' where a trailing comma yields an empty field; firmware printing labels ('amp1') or hex values; serial corruption garbling only the tail of the line.

Common situations: Debug firmware builds that insert verbose prints inside the CSV row; hand-crafted replay lines with wrong field types; baud-rate mismatch producing semi-decodable garbage.

Related errors


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/34d7262e794f1d89. Report an issue: GitHub.