When its output isn't a terminal, nu 0.116 draws the mark before the message as x rather than ×, so Message fell back to the header line, nu::shell::column_not_found, and lost what was wrong. The x counts only after nu's Error: header.
- commit
- 02f429a61b69db900df872543731509f7c8eb229
- parent
- c2d6922b906295b88b644cf5a2c72b156e6368cd
- author
- Dami <dami.etoile@gmail.com>
- ci
- ✓ passed in 31s, signed by cat
- kind
- fix risk score 1.1 of 3, Jev's estimate
ci attestation
forge-attestation 1 type ci commit 02f429a61b69db900df872543731509f7c8eb229 tree 87d90edbfb102f0afad7530eb482394bea92bf83 script .forge/ci feebc265e71f534242c13394fa56df0c5fe19cfb result pass exit 0 started 2026-10-17T22:31:21Z duration 31s runner (not shown here; refs/notes/ci has it) system Darwin 25.5.0 arm64 env host log sha256:78138715474749307dc286831ba0d61c43e89bfee2fd6ed609422b3a3fe7dae3 74 lines |ok github.com/FelineStateMachine/012/internal/cowork (cached) |ok github.com/FelineStateMachine/012/internal/diff (cached) |ok github.com/FelineStateMachine/012/internal/fileio 2.965s |ok github.com/FelineStateMachine/012/internal/formula (cached) |ok github.com/FelineStateMachine/012/internal/functions (cached) |ok github.com/FelineStateMachine/012/internal/headless (cached) |ok github.com/FelineStateMachine/012/internal/jev 2.275s |ok github.com/FelineStateMachine/012/internal/keyring (cached) |ok github.com/FelineStateMachine/012/internal/live (cached) |ok github.com/FelineStateMachine/012/internal/locale (cached) |ok github.com/FelineStateMachine/012/internal/macro (cached) |ok github.com/FelineStateMachine/012/internal/mcp 1.163s |ok github.com/FelineStateMachine/012/internal/notebook (cached) |ok github.com/FelineStateMachine/012/internal/numfmt (cached) |ok github.com/FelineStateMachine/012/internal/nuon 1.795s |ok github.com/FelineStateMachine/012/internal/nushell 1.786s |? github.com/FelineStateMachine/012/internal/nushell/module [no test files] |ok github.com/FelineStateMachine/012/internal/paged (cached) |ok github.com/FelineStateMachine/012/internal/room (cached) |ok github.com/FelineStateMachine/012/internal/serve 3.140s |ok github.com/FelineStateMachine/012/internal/sheet (cached) |? github.com/FelineStateMachine/012/internal/stress [no test files] |? github.com/FelineStateMachine/012/internal/stress/benchrec [no test files] |ok github.com/FelineStateMachine/012/internal/telemetry 3.423s |ok github.com/FelineStateMachine/012/internal/ui 8.302s |ok github.com/FelineStateMachine/012/internal/ui/choicebar (cached) |ok github.com/FelineStateMachine/012/internal/ui/cmdhelp (cached) |ok github.com/FelineStateMachine/012/internal/ui/cmdline (cached) |ok github.com/FelineStateMachine/012/internal/ui/evalview (cached) |ok github.com/FelineStateMachine/012/internal/ui/filterpick (cached) |ok github.com/FelineStateMachine/012/internal/ui/findbar (cached) |ok github.com/FelineStateMachine/012/internal/ui/formula (cached) |ok github.com/FelineStateMachine/012/internal/ui/lineedit (cached) |ok github.com/FelineStateMachine/012/internal/ui/nbview 1.743s |? github.com/FelineStateMachine/012/internal/ui/overlay [no test files] |ok github.com/FelineStateMachine/012/internal/ui/picker (cached) |ok github.com/FelineStateMachine/012/internal/ui/review (cached) |ok github.com/FelineStateMachine/012/internal/ui/rowtext (cached) |ok github.com/FelineStateMachine/012/internal/ui/rules (cached) |ok github.com/FelineStateMachine/012/internal/ui/shortcuts (cached) |ok github.com/FelineStateMachine/012/internal/ui/sortbar (cached) |ok github.com/FelineStateMachine/012/internal/ui/srcview (cached) |ok github.com/FelineStateMachine/012/internal/ui/suggest (cached) |ok github.com/FelineStateMachine/012/internal/ui/tabstrip (cached) |ok github.com/FelineStateMachine/012/internal/ui/theme (cached) |ok github.com/FelineStateMachine/012/internal/ui/themepicker (cached) |ok github.com/FelineStateMachine/012/internal/ui/transfer (cached) |ok github.com/FelineStateMachine/012/internal/value (cached) |? github.com/FelineStateMachine/012/scripts/doccheck [no test files] |? github.com/FelineStateMachine/012/scripts/doclint [no test files] |ok github.com/FelineStateMachine/012/scripts/install 3.122s |=== e2e: ok, done at 26s |cd e2e && PKG_CONFIG_PATH=/Users/dami/.cache/012/deps/ghostty/share/pkgconfig go test -count=1 ./... |ok github.com/FelineStateMachine/012/e2e 25.360s |=== speed: ok, done at 31s |go test ./internal/ui -run '^(TestSpeed|TestSharedEditWithinAFrame|TestStreamGridAtFrameSpeed)$' -count=1 -speed |ok github.com/FelineStateMachine/012/internal/ui 2.455s |go test ./internal/ui/nbview -run '^(TestScrollsAtFrameSpeed)$' -count=1 |ok github.com/FelineStateMachine/012/internal/ui/nbview 1.591s |=== make check: 31s
Signature: good, cat
| M | internal/ | 6 | +++++- |
| M | internal/ | 7 | +++++++ |
@@ -251,7 +251,8 @@ func nuArgs(job Job, script, dir string) ([]string, error) {
251251 }252252 253253 // Message is the line of nu's standard error that says what went wrong:254-// the one marked ×, or the first, or how the process ended.254+// the one marked × (an ASCII x when nu doesn't draw in Unicode, as when255+// its output isn't a terminal), or the first, or how the process ended.255256 func Message(stderr string, err error) string {256257 first := ""257258 for line := range strings.SplitSeq(stderr, "\n") {@@ -259,6 +260,9 @@ func Message(stderr string, err error) string {
259260 if rest, ok := strings.CutPrefix(line, "×"); ok {260261 return strings.TrimSpace(rest)261262 }263+ if rest, ok := strings.CutPrefix(line, "x "); ok && strings.HasPrefix(first, "Error:") {264+ return strings.TrimSpace(rest)265+ }262266 if first == "" && line != "" {263267 first = line264268 }@@ -94,6 +94,13 @@ func TestMessage(t *testing.T) {
9494 if got := Message(stderr, errors.New("exit status 1")); got != "Cannot find column 'xyz'" {9595 t.Errorf("message %q", got)9696 }97+ ascii := "Error: nu::shell::column_not_found\n\n x Cannot find column 'xyz'\n ,-[source:1:6]\n"98+ if got := Message(ascii, errors.New("exit status 1")); got != "Cannot find column 'xyz'" {99+ t.Errorf("ascii message %q", got)100+ }101+ if got := Message("x is not a command\n", errors.New("exit status 1")); got != "x is not a command" {102+ t.Errorf("unmarked message %q", got)103+ }97104 if got := Message("", errors.New("exit status 1")); got != "exit status 1" {98105 t.Errorf("message %q", got)99106 }