Skip to content

Error redirecting output of a subexspression. This is a bug apparrently... #15416

@incansvl

Description

@incansvl

Describe the bug

I have a script that will (when it's working...) collect statistics on it's activities in a pair of records, then writes these out at the end of the program. The following line writes the "last run record" as JSON to a static file-

$RunRecord | to json o> $RunRecordPath

This works correctly. However I originally wrote it as-

($RunRecord | to json) o> $RunRecordPath (note the parentheses)

This fails to compile with the error-

Error: nu::shell::ir_eval_error

  × IR evaluation error: Tried to write to file #0, but it is not open
    ╭─[/home/username/.../clerk.nu:49:28]
 48 │     # Write the run record data
 49 │     ($RunRecord | to json) o> $RunRecordPath
    ·                            ─┬
    ·                             ╰── while running this code
 50 │     log ($Stats | to json --raw)
    ╰────
  help: this is a bug, please report it at https://github.com/nushell/nushell/issues/new along with the code you were running if able

So, I am duly reporting the issue.

How to reproduce

The following shows the context in which the error occurs-

let ScriptVersion = '0.0.1'
let RunRecordPath = '/var/log/clerk/lastrun.data'
touch_p $RunRecordPath               # initialise run record file
let Interactive: bool = is-fg

let users = real_users

def main [FullScanMode=false] {
    let ScanMode = if $FullScanMode {'Full'} else {'Incremental'}
    
    mut Stats = {
        'Interactive' : $Interactive
        'ScanMode' : $ScanMode
    }
    mut RunRecord = {
        'Interactive' : $Interactive
        'ScanMode' : $ScanMode
        'RunStart' : (script_start_time | format date "%Y-%m-%d %H:%M:%S")
    }

    # Write the run record and log data
    ($RunRecord | to json) o> $RunRecordPath
    log ($Stats | to json --raw)
}

# Get the list of real (human) users
def real_users [] {
    getent passwd ...(cd /home; ls | get name)
        | from csv -n -s ':'
        | where column2 > 1000 and column2 < 6500
        | get column0
}

# Detect if script has root effective uid. Note the return value
# of id -u is treated as a string by nu
def is-root [] {
    if (id -u) == '0' { true } else { false }
}

# Detect if script is in foreground / background
def is-fg [] {
    try { tty -s; true } catch { false }
}

# touch (create) a file, also creating any missing intermediate
# directories in the path. Similar to the builtin mkdir
def touch_p [path: string] {
    mkdir ($path | path expand | path dirname)
    touch ($path | path expand)
}

# Returns start timestamp of the process (as datetime)
def script_start_time [] {
    ps -l | where pid == $nu.pid | get start_time.0
}

# Write an entry to the systemd journal
# Retrieve data using "journalctl -t clerk"
def log [msg: string, ident= 'clerk', prio= 'info'] {
    echo $msg | systemd-cat -t $ident -p $prio
}

Expected behavior

I expected the parentheses to force execution of the commands (not necessary as it turns out) but otherwise not change the outcome, the output of the parenthesised expression should be the same as the output of the last command in the enclosed pipeline I think (correct?)

Configuration

| key                | value                                                            |
| ------------------ | ---------------------------------------------------------------- |
| version            | 0.103.0                                                          |
| major              | 0                                                                |
| minor              | 103                                                              |
| patch              | 0                                                                |
| branch             | makepkg                                                          |
| commit_hash        | c98642647878b4f66fb7e38388a3973071b0e27b                         |
| build_os           | linux-x86_64                                                     |
| build_target       | x86_64-unknown-linux-gnu                                         |
| rust_version       | rustc 1.85.1 (4eb161250 2025-03-15) (Arch Linux rust 1:1.85.1-1) |
| cargo_version      | cargo 1.85.1 (d73d2caf9 2024-12-31)                              |
| build_time         | 2025-03-21 07:50:32 +00:00                                       |
| build_rust_channel | release                                                          |
| allocator          | standard                                                         |
| features           | default, sqlite, trash                                           |
| installed_plugins  |                                                                  |

Metadata

Metadata

Assignees

No one assigned

    Labels

    status:needs-triageAn issue that hasn't had any proper look

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions