{"record":{"id":"08a12f743d55f2b2","repo":"ruvnet/RuView","slug":"cannot-read-proc-net-wireless-exc","errorCode":null,"errorMessage":"Cannot read /proc/net/wireless: {exc}","messagePattern":"Cannot read /proc/net/wireless: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"archive/v1/src/sensing/rssi_collector.py","lineNumber":218,"sourceCode":"        except OSError as exc:\n            return False, f\"Cannot read /proc/net/wireless: {exc}\"\n\n        if interface not in content:\n            names = cls._parse_interface_names(content)\n            return False, (\n                f\"Interface '{interface}' not listed in /proc/net/wireless. \"\n                f\"Available: {names or '(none)'}. \"\n                f\"Ensure the interface is up and associated with an AP.\"\n            )\n        return True, \"ok\"\n\n    # -- internals -----------------------------------------------------------\n\n    def _validate_interface(self) -> None:\n        \"\"\"Check that the interface exists on this machine.\"\"\"\n        available, reason = self.is_available(self._interface)\n        if not available:\n            raise RuntimeError(reason)\n\n    @staticmethod\n    def _parse_interface_names(proc_content: str) -> List[str]:\n        \"\"\"Extract interface names from /proc/net/wireless content.\"\"\"\n        names: List[str] = []\n        for line in proc_content.splitlines()[2:]:  # skip header lines\n            parts = line.split(\":\")\n            if len(parts) >= 2:\n                names.append(parts[0].strip())\n        return names\n\n    def _sample_loop(self) -> None:\n        interval = 1.0 / self._rate\n        while self._running:\n            t0 = time.monotonic()\n            try:\n                sample = self._read_sample()\n                self._buffer.append(sample)","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/archive/v1/src/sensing/rssi_collector.py#L200-L236","documentation":"LinuxWifiCollector.is_available() already confirmed /proc/net/wireless exists via os.path.exists, but the subsequent open() raised an OSError (permission denied, broken procfs mount, or the file vanished between check and read). The reason string 'Cannot read /proc/net/wireless: {exc}' is returned as unavailable and _validate_interface() re-raises it as RuntimeError when the collector starts. This is a host-environment error: the Linux wireless procfs interface is present but not readable by the current process.","triggerScenarios":"Calling LinuxWifiCollector(interface=...).start() (which runs _validate_interface -> is_available) on a host where open('/proc/net/wireless') raises OSError: EACCES under a restrictive container runtime or SELinux policy, a read-only or corrupted procfs mount, or a race where the file is removed after the exists() check.","commonSituations":"Running the collector inside Docker/Podman with a masked or restricted /proc; hardened or embedded Linux images that mount procfs with unusual options; running as an unprivileged user on systems where /proc/net/wireless is root-only; WSL2 with a partially exposed procfs.","solutions":["Run the app on a normal Linux host with a WiFi adapter and a standard procfs mount; host RSSI sensing is not supported in restricted sandboxes.","Diagnose the mount and permissions: run 'mount | grep proc' and 'ls -l /proc/net/wireless' as the same user the service runs as.","If containerized, run with host network and an unmasked /proc (for example 'docker run --network host -v /proc:/proc' style setups) or move RSSI collection to the host.","For camera-free perception in restricted environments, use the ESP32 CSI node firmware path instead of host WiFi sensing, which does not depend on /proc/net/wireless."],"exampleFix":"# before\ncollector = LinuxWifiCollector(interface='wlan0')\ncollector.start()  # raises RuntimeError: Cannot read /proc/net/wireless: ...\n\n# after\navailable, reason = LinuxWifiCollector.is_available('wlan0')\nif not available:\n    raise SystemExit(f'RSSI sensing unavailable on this host: {reason}')\ncollector = LinuxWifiCollector(interface='wlan0')\ncollector.start()","handlingStrategy":"validation","validationCode":"available, reason = LinuxWifiCollector.is_available('wlan0')\nif not available:\n    raise SystemExit(f'RSSI sensing unavailable: {reason}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always call LinuxWifiCollector.is_available(interface) before constructing or starting the collector; it returns (False, reason) instead of raising.","Add a deployment check that /proc/net/wireless is readable by the service user before enabling host RSSI sensing.","Do not enable the Linux RSSI collector in Docker/WSL deployments; route sensing to the ESP32 CSI node there."],"tags":["linux","wifi","rssi","procfs","permissions","hardware"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}