[GH-ISSUE #6733] [Bug] CSV autodetection loses the filename hint for recordings named .csv #4096

Closed
opened 2026-10-31 00:46:48 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6733

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

A valid CSV recording whose basename is .csv decodes directly with the configured sigrok installation, but decode-signal-recording returns execution_failure when input_format is omitted. The identical bytes named capture.csv or .capture.csv decode successfully through REA. Explicit input_format: "csv" also restores decoding of .csv.

This was reproduced with the real producer and Linux resource limiter through both the checkout's built CLI and the source SignalRecordingService/SigrokRecordingProvider. No simulated producer or physical hardware was used.

Reproduction

Use Linux, the checkout's pinned Node toolchain and built runtime, and an absolute REA_SIGROK_COMMAND pointing to sigrok-cli with libsigrokdecode. From the checkout root, create this self-contained 136-byte recording of an I2C address probe:

probe_dir=$(mktemp -d)
python3 - "$probe_dir" <<'PYCODE'
from pathlib import Path
import sys
root = Path(sys.argv[1])
rows = ['SCL,SDA', '1,1', '1,0']
for shift in range(7, -1, -1):
    bit = (0xa0 >> shift) & 1
    rows.extend([f'0,{bit}', f'1,{bit}', f'0,{bit}'])
rows.extend(['0,0', '1,0', '0,0', '0,0', '1,0', '1,1'])
source = '\n'.join(rows) + '\n'
for name in ['.csv', 'capture.csv', '.capture.csv']:
    (root / name).write_text(source)
PYCODE

# Direct producer: exit 0, 13 annotation lines, empty stderr.
"$REA_SIGROK_COMMAND" --dont-scan --input-file="$probe_dir/.csv" \
  --protocol-decoders=i2c:scl=SCL:sda=SDA --protocol-decoder-samplenum

# REA: exit 1, execution_failure.
node scripts/rea.mjs decode-signal-recording "$probe_dir/.csv" \
  --decoders i2c:scl=SCL:sda=SDA --all_lines --format json

# Controls: each exits 0 and returns the same 13 annotation lines.
node scripts/rea.mjs decode-signal-recording "$probe_dir/.csv" \
  --decoders i2c:scl=SCL:sda=SDA --input_format csv --all_lines --format json
node scripts/rea.mjs decode-signal-recording "$probe_dir/capture.csv" \
  --decoders i2c:scl=SCL:sda=SDA --all_lines --format json
node scripts/rea.mjs decode-signal-recording "$probe_dir/.capture.csv" \
  --decoders i2c:scl=SCL:sda=SDA --all_lines --format json

The equivalent command argument vectors were executed once per case for the reduced fixture. Source-service confirmation independently reproduced the failing dotfile and the ordinary-name/explicit-format controls. A larger three-byte fixture had the same result before reduction. All input files retained identical SHA-256 values after the probes.

Expected behavior

Autodetection should retain the filename information needed by sigrok to recognize a supported recording, including this basename. The recording guide promises that the private copy retains the selected recording's final suffix so filename-based autodetection receives its hint. Direct producer execution confirms that .csv supplies a working hint for this exact valid input.

Impact and scope

The demonstrated name blocks default decoding of a valid file and produces advice to run rea doctor, despite a working installation. The observed scope is CSV input with this basename; other formats and transport-level MCP behavior were not tested. Selecting input_format: "csv" is a verified workaround that preserves the source and annotations. Renaming the same bytes to a conventional .csv filename also passes.

REA version

Executed source revision 3c5c887a2cc7371a94fe0fd8b6c478dbf2af60db, package manifest and built CLI version 6.7.0. The published npm artifact was not executed.

Runtime and platform

Node.js v26.12.1; Linux x86_64; sigrok-cli 0.7.2; runtime libsigrok 0.5.2-git-9ffa3638; libsigrokdecode 0.5.3; real util-linux prlimit. Packaged sigrok tools and decoder modules were extracted into an isolated temporary directory without changing the host installation.

Target and artifact context

A generated 136-byte CSV containing SCL,SDA logic channels and an I2C write-address probe for address 0x50. No hardware, executable target, private data, or malformed input.

Interface

CLI

Earliest failure stage

Capture or observation

Relevant output or evidence

The failing CLI result includes:

{
  "code": "execution_failure",
  "retryable": false,
  "details": {
    "provider_id": "sigrok-recording",
    "operation": "decode_signal_recording",
    "diagnostics": {
      "exit_code": 1,
      "stdout": "",
      "stderr": "Error: no input module found for this file.\n"
    }
  }
}

The explicit-format control reports --input-file=recording and --input-format=csv in tool.arguments; conventional-name controls report --input-file=recording.csv. All successful controls and direct producer runs return the identical 13 lines, including Address write: 50, ACK, and Stop; their stderr/diagnostics are empty. Their output windows report total_lines: 13, returned_lines: 13, and has_more: false.

Typed outcome or recovery expected

Successful decode Evidence for the omitted-format dotfile case, with the same 13 literal annotation lines as the controls. Preserve the passing ordinary-name and explicit-format behavior; do not require the caller to rename the file or override autodetection.

Analysis or suspected cause

Source-derived: snapshot naming appends extname(input.path) to recording. That API treats .csv as a dotfile with no extension, so the private name loses the producer's usable suffix hint. By contrast, released libsigrok's CSV matcher recognizes any filename ending in .csv, including the original basename.

Additional context

Follow-up to closed #6580: its conventional capture.csv case now passes, as the controls above demonstrate. This report isolates the remaining .csv basename case in the current suffix-preservation implementation, where extname supplies an empty string. Open and closed searches found that related report and no report of this remaining case.

NOT_ENOUGH_INFO: the first affected REA release was not established. This report concerns current-main behavior; the published package was not tested.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A supported default decoding request fails for an ordinary valid filename while the same bytes decode directly and through both control paths. The demonstrated reach is bounded to this filename/format combination.
  • Workaround status: available
  • Workaround basis: Explicit input_format: "csv" decoded the original dotfile with annotation text identical to direct sigrok output; conventional filenames also passed with the same bytes.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6733 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Evidence, artifacts, or reconstruction ## Observed behavior A valid CSV recording whose basename is `.csv` decodes directly with the configured sigrok installation, but `decode-signal-recording` returns `execution_failure` when `input_format` is omitted. The identical bytes named `capture.csv` or `.capture.csv` decode successfully through REA. Explicit `input_format: "csv"` also restores decoding of `.csv`. This was reproduced with the real producer and Linux resource limiter through both the checkout's built CLI and the source `SignalRecordingService`/`SigrokRecordingProvider`. No simulated producer or physical hardware was used. ## Reproduction Use Linux, the checkout's pinned Node toolchain and built runtime, and an absolute `REA_SIGROK_COMMAND` pointing to sigrok-cli with libsigrokdecode. From the checkout root, create this self-contained 136-byte recording of an I2C address probe: ```sh probe_dir=$(mktemp -d) python3 - "$probe_dir" <<'PYCODE' from pathlib import Path import sys root = Path(sys.argv[1]) rows = ['SCL,SDA', '1,1', '1,0'] for shift in range(7, -1, -1): bit = (0xa0 >> shift) & 1 rows.extend([f'0,{bit}', f'1,{bit}', f'0,{bit}']) rows.extend(['0,0', '1,0', '0,0', '0,0', '1,0', '1,1']) source = '\n'.join(rows) + '\n' for name in ['.csv', 'capture.csv', '.capture.csv']: (root / name).write_text(source) PYCODE # Direct producer: exit 0, 13 annotation lines, empty stderr. "$REA_SIGROK_COMMAND" --dont-scan --input-file="$probe_dir/.csv" \ --protocol-decoders=i2c:scl=SCL:sda=SDA --protocol-decoder-samplenum # REA: exit 1, execution_failure. node scripts/rea.mjs decode-signal-recording "$probe_dir/.csv" \ --decoders i2c:scl=SCL:sda=SDA --all_lines --format json # Controls: each exits 0 and returns the same 13 annotation lines. node scripts/rea.mjs decode-signal-recording "$probe_dir/.csv" \ --decoders i2c:scl=SCL:sda=SDA --input_format csv --all_lines --format json node scripts/rea.mjs decode-signal-recording "$probe_dir/capture.csv" \ --decoders i2c:scl=SCL:sda=SDA --all_lines --format json node scripts/rea.mjs decode-signal-recording "$probe_dir/.capture.csv" \ --decoders i2c:scl=SCL:sda=SDA --all_lines --format json ``` The equivalent command argument vectors were executed once per case for the reduced fixture. Source-service confirmation independently reproduced the failing dotfile and the ordinary-name/explicit-format controls. A larger three-byte fixture had the same result before reduction. All input files retained identical SHA-256 values after the probes. ## Expected behavior Autodetection should retain the filename information needed by sigrok to recognize a supported recording, including this basename. The [recording guide](https://github.com/morluto/rea/blob/3c5c887a2cc7371a94fe0fd8b6c478dbf2af60db/docs/signal-recordings.md#L38-L41) promises that the private copy retains the selected recording's final suffix so filename-based autodetection receives its hint. Direct producer execution confirms that `.csv` supplies a working hint for this exact valid input. ## Impact and scope The demonstrated name blocks default decoding of a valid file and produces advice to run `rea doctor`, despite a working installation. The observed scope is CSV input with this basename; other formats and transport-level MCP behavior were not tested. Selecting `input_format: "csv"` is a verified workaround that preserves the source and annotations. Renaming the same bytes to a conventional `.csv` filename also passes. ## REA version Executed source revision `3c5c887a2cc7371a94fe0fd8b6c478dbf2af60db`, package manifest and built CLI version `6.7.0`. The published npm artifact was not executed. ## Runtime and platform Node.js v26.12.1; Linux x86_64; sigrok-cli 0.7.2; runtime libsigrok 0.5.2-git-9ffa3638; libsigrokdecode 0.5.3; real util-linux prlimit. Packaged sigrok tools and decoder modules were extracted into an isolated temporary directory without changing the host installation. ## Target and artifact context A generated 136-byte CSV containing `SCL,SDA` logic channels and an I2C write-address probe for address 0x50. No hardware, executable target, private data, or malformed input. ## Interface CLI ## Earliest failure stage Capture or observation ## Relevant output or evidence The failing CLI result includes: ```json { "code": "execution_failure", "retryable": false, "details": { "provider_id": "sigrok-recording", "operation": "decode_signal_recording", "diagnostics": { "exit_code": 1, "stdout": "", "stderr": "Error: no input module found for this file.\n" } } } ``` The explicit-format control reports `--input-file=recording` and `--input-format=csv` in `tool.arguments`; conventional-name controls report `--input-file=recording.csv`. All successful controls and direct producer runs return the identical 13 lines, including `Address write: 50`, `ACK`, and `Stop`; their stderr/diagnostics are empty. Their output windows report `total_lines: 13`, `returned_lines: 13`, and `has_more: false`. ## Typed outcome or recovery expected Successful decode Evidence for the omitted-format dotfile case, with the same 13 literal annotation lines as the controls. Preserve the passing ordinary-name and explicit-format behavior; do not require the caller to rename the file or override autodetection. ## Analysis or suspected cause Source-derived: [snapshot naming](https://github.com/morluto/rea/blob/3c5c887a2cc7371a94fe0fd8b6c478dbf2af60db/src/signals/SigrokRecordingProvider.ts#L180-L184) appends `extname(input.path)` to `recording`. That API treats `.csv` as a dotfile with no extension, so the private name loses the producer's usable suffix hint. By contrast, [released libsigrok's CSV matcher](https://github.com/sigrokproject/libsigrok/blob/libsigrok-0.5.2/src/input/csv.c#L1100-L1110) recognizes any filename ending in `.csv`, including the original basename. ## Additional context Follow-up to closed [#6580](https://github.com/morluto/rea/issues/6580): its conventional `capture.csv` case now passes, as the controls above demonstrate. This report isolates the remaining `.csv` basename case in the current suffix-preservation implementation, where `extname` supplies an empty string. Open and closed searches found that related report and no report of this remaining case. NOT_ENOUGH_INFO: the first affected REA release was not established. This report concerns current-main behavior; the published package was not tested. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: A supported default decoding request fails for an ordinary valid filename while the same bytes decode directly and through both control paths. The demonstrated reach is bounded to this filename/format combination. - Workaround status: available - Workaround basis: Explicit `input_format: "csv"` decoded the original dotfile with annotation text identical to direct sigrok output; conventional filenames also passed with the same bytes.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4096
No description provided.