OILS / doc / error-catalog.md View on Github | oils.pub

636 lines, 448 significant
1---
2default_highlighter: oils-sh
3---
4
5Oils Error Catalog, With Hints
6==================
7
8This doc lists errors from Oils (both [OSH]($xref) and [YSH]($xref)), with
9hints to help you fix them.
10
11Each error is associated with a code like `OILS-ERR-42`, a string that search
12engines should find.
13
14<!--
15Later, we could have a URL shortener, like https://oils.err/42
16-->
17
18<div id="toc">
19</div>
20
21## How to Contribute
22
23If you see an error that you don't understand:
24
251. Ask a question on `#oil-help` on [Zulip]($xref:zulip). What's the problem,
26 and what's the solution?
271. Then `grep` the source code for the confusing error message. Tag it with a
28 string like `OILS-ERR-43`, picking a new number according to the conventions
29 below.
301. Add a tagged section below, with hints and explanations.
31 - Quote the error message. You may want copy and paste from the output of
32 `doc/error-catalog.sh`, or
33 `test/{parse,runtime,ysh-parse,ysh-runtime}-errors.sh`. Add an HTML
34 comment `<!-- -->` about that.
35 - Link to relevant sections in the [**Oils Reference**](ref/index.html).
361. Optionally, add your name to the acknowledgements list at the end of this
37 doc.
38
39Note that error messages are **hard** to write, because a single error could
40result from many different user **intentions**!
41
42### To Preview this Doc
43
44Right now I use this command:
45
46 build/doc.sh split-and-render doc/error-catalog.md
47
48Then paste this into your browser:
49
50 file:///home/andy/git/oils-for-unix/oils/_release/VERSION/doc/error-catalog.html
51
52(Replace with your home dir)
53
54## Parse Errors - Rejected Input
55
56Roughly speaking, a parse error means that text input was **rejected**, so the
57shell didn't try to do anything.
58
59Examples:
60
61 echo ) # Shell syntax error
62
63 type -z # -z flag not accepted
64
65These error codes start at `10`.
66
67### OILS-ERR-10
68
69<!--
70Generated with:
71test/ysh-parse-errors.sh test-func-var-checker
72-->
73
74```
75 setvar x = true
76 ^
77[ -c flag ]:3: setvar couldn't find matching 'var x' (OILS-ERR-10)
78```
79
80- Did you forget to declare the name with the [var](ref/chap-ysh-cmd.html#var)
81 keyword?
82- Did you mean to use the [setglobal](ref/chap-ysh-cmd.html#setglobal)
83 keyword?
84
85Related help topics:
86
87- [setvar](ref/chap-ysh-cmd.html#setvar)
88
89### OILS-ERR-11
90
91<!--
92Generated with:
93test/ysh-parse-errors.sh ysh_c_strings (this may move)
94-->
95
96```
97 echo $'\z'
98 ^
99[ -c flag ]:1: Invalid char escape in C-style string literal (OILS-ERR-11)
100```
101
102- Did you mean `$'\\z'`? Backslashes must be escaped in `$''` and `u''` and
103 `b''` strings.
104- Did you mean something like `$'\n'`? Only valid escapes are accepted in YSH.
105
106Related help topics:
107
108- [osh-string](ref/chap-word-lang.html#osh-string) (word language)
109- [ysh-string](ref/chap-expr-lang.html#ysh-string) (expression language)
110
111### OILS-ERR-12
112
113<!--
114Generated with:
115test/ysh-parse-errors.sh ysh_dq_strings (this may move)
116-->
117
118```
119 echo "\z"
120 ^
121[ -c flag ]:1: Invalid char escape in double quoted string (OILS-ERR-12)
122```
123
124- Did you mean `"\\z"`? Backslashes must be escaped in double-quoted strings.
125- Did you mean something like `"\$"`? Only valid escapes are accepted in YSH.
126- Did you to use single quotes, like `u'\n'` rather than `u"\n"`?
127
128Related help topics:
129
130- [osh-string](ref/chap-word-lang.html#osh-string) (word language)
131- [ysh-string](ref/chap-expr-lang.html#ysh-string) (expression language)
132
133### OILS-ERR-13
134
135<!--
136Generated with:
137test/ysh-parse-errors.sh ysh_bare_words (this may move)
138-->
139
140```
141 echo \z
142 ^~
143[ -c flag ]:1: Invalid char escape in unquoted word (OILS-ERR-13)
144```
145
146- Did you mean `\\z`? Backslashes must be escaped in unquoted words.
147- Did you mean something like `\$`? Only valid escapes are accepted in YSH.
148
149### OILS-ERR-14
150
151<!--
152Generated with:
153test/ysh-parse-errors.sh test-parse-dparen
154-->
155
156```
157 if ((1 > 0 && 43 > 42)); then echo yes; fi
158 ^~
159[ -c flag ]:1: Bash (( not allowed in YSH (no_parse_dparen, see OILS-ERR-14 for wart)
160```
161
162Two likely causes:
163
164- Do you need to rewrite bash arithmetic as YSH arithmetic (which is
165 Python-like)?
166- Do you need to work around an [unfortunate wart](warts.html#two-left-parens-should-be-separated-by-space) in YSH?
167
168Examples:
169
170 if (1 > 0 and 43 > 42) { # YSH-style
171 echo yes
172 }
173
174 if ( (x + 1) < n) { # space between ( ( avoids ((
175 echo yes
176 }
177
178### OILS-ERR-15
179
180```
181 if (a || b && c) {
182 ^~
183[ -c flag ]:2: Use 'or' in expression mode (OILS-ERR-15)
184```
185
186Expression mode uses `not or and`, rather than `! || &&`. See [Command vs.
187Expression Mode](command-vs-expression-mode.html) for details.
188
189
190No:
191
192 if (!a || b && c) {
193 echo no
194 }
195
196Yes:
197
198 if (not a or b and c) {
199 echo yes
200 }
201
202
203Command mode is the opposite; it uses `! || &&`, rather than `not or and`:
204
205No:
206
207 # Command mode
208 if not test --dir a or test --dir b and test --dir c {
209 echo no
210 }
211
212Yes:
213
214 # Command mode
215 if ! test --dir a || test --dir b && test --dir c {
216 echo yes
217 }
218
219### OILS-ERR-16
220
221```
222 for x in (1 .. 5) {
223 ^~
224[ -c flag ]:1: Use ..< for half-open range, or ..= for closed range (OILS-ERR-16)
225```
226
227<!--
228Similar to
229test/ysh-parse-errors.sh test-expr-range
230-->
231
232There are two ways to construct a [Range](ref/chap-expr-lang#range). The `..<`
233operator is for half-open ranges and the `..=` operator is for closed ranges:
234
235 for i in (0 ..< 3) {
236 echo $i
237 }
238 => 0
239 => 1
240 => 2
241
242 for i in (0 ..= 3) {
243 echo $i
244 }
245 => 0
246 => 1
247 => 2
248 => 3
249
250### OILS-ERR-17
251
252```
253 echo --flag=u'foo'
254 ^
255[ -c flag ]:1: Invalid quoted word part in YSH (OILS-ERR-17)
256```
257
258<!--
259test/ysh-parse-errors.sh test-string-sigil-pair
260-->
261
262In YSH, `--flag='foo'` is allowed, but `--flag=u'foo\n'` is not. In the latter
263case, it's not clear if the `u` is literal.
264
265Try one of these alternatives:
266
267 ysh$ echo u'--flag=foo\n' # quote the whole thing
268
269 ysh$ echo --flag u'foo\n' # space instead of =
270
271 ysh$ echo --flag=$myvar # assign to variable first
272
273 ysh$ echo $['--flag=' ++ myvar] # expression sub
274
275
276### OILS-ERR-18
277
278```
279 echo "date = `date`"
280 ^
281[ -c flag ]:1: Backtick should be $(cmd) or \` (no_parse_backticks, OILS-ERR-18)
282```
283
284- Did you mean to use `$(date)` instead?
285 - This is the only syntax for command substitution in YSH, because it nests
286 cleanly.
287- Did you mean to escape the backtick with `` \` ``?
288 - (OSH and YSH have the same string literal syntax, including the
289 backslash-quoted backtick `` \` ``.)
290
291### OILS-ERR-19
292
293```
294 ( cd /tmp && ls )
295 ^
296[ -c flag ]:1: Subshell syntax ( ) isn't allowed in YSH (OILS-ERR-19)
297```
298
299- In YSH, you can use `forkwait { echo hi }` to create a subshell.
300- You may not need a subshell; you may use idioms like `cd /tmp { ls }` to save
301 and restore state.
302
303Note that, in shell, the `( )` syntax does **not** simply group commands. The
304`{ }` syntax is for grouping commands.
305
306This is a common mistake because parentheses are for grouping in other
307programming languages.
308
309### OILS-ERR-20
310
311
312```
313 var x = ' \n '
314 ^~~~
315[ -c flag ]:1: Ambiguous backslash: add explicit r'' or u'' prefix (OILS-ERR-20)
316```
317
318Did you mean `r' \n '`? This is a raw string with a literal backslash.
319
320Or did you mean `u' \n '` or `b' \n '`? These are strings with C-style
321escapes.
322
323YSH wants you to be explicit about what backslashes mean.
324
325## Runtime Errors - Traditional Shell
326
327These errors may occur in shells like [bash]($xref) and [zsh]($xref).
328
329They're numbered starting from `100`. (If we have more than 90 parse errors,
330we can start a new section, like `300`.)
331
332### OILS-ERR-100
333
334<!--
335Generated with:
336test/runtime-errors.sh test-command-not-found
337-->
338
339```
340 findz
341 ^~~~~
342[ -c flag ]:1: Command 'findz' not found (OILS-ERR-100)
343```
344
345The shell tried to execute an external command, but couldn't.
346
347- Did you misspell a command name?
348- Did you misspell a shell function or a YSH `proc`?
349- Is the file in your `$PATH`? The `PATH` variable is a colon-separated list
350 of directories, where executable files may live.
351- Is `findz` file executable bit set? (`chmod +x`)
352
353### OILS-ERR-101
354
355<!--
356Generated with:
357test/runtime-errors.sh test-assoc-array
358-->
359
360Let's look at **three** instances of this error.
361
362```
363 declare -A assoc; assoc[x]=1
364 ^~~~~~
365[ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101)
366```
367
368- Is `x` a string? Then add quotes: `assoc['x']=1`
369- Is `x` a variable? Then write: `assoc[$x]=1`
370
371---
372
373Same idea here:
374
375```
376 declare -A assoc; echo ${assoc[x]}
377 ^
378[ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101)
379```
380
381- Is `x` a string? Then add quotes: `${assoc['x']}`
382- Is `x` a variable? Then write: `${assoc[$x]}`
383
384---
385
386The third example is **tricky** because `unset` takes a **string**. There's an
387extra level of parsing, which:
388
389- Implies an extra level of quoting
390- Causes OSH to display the following **nested** error message
391
392```
393 assoc[k]
394 ^
395[ dynamic LHS word at line 1 of [ -c flag ] ]:1
396
397 declare -A assoc; key=k; unset "assoc[$key]"
398 ^
399[ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101)
400```
401
402To fix it, consider using **single quotes**:
403
404 unset 'assoc[$key]'
405
406---
407
408- This is the error in [Parsing Bash is
409 Undecidable](https://www.oilshell.org/blog/2016/10/20.html) (2016)
410- Also mentioned in [Known Differences](known-differences.html)
411
412
413### OILS-ERR-102
414
415```
416 var cmd = ^(seq 3)
417 ^~~
418[ stdin ]:1: Command 'seq' not found in pure mode (OILS-ERR-102)
419```
420
421The shell tried to execute a command in pure mode, but couldn't.
422
423In pure mode, only user-defined procs and a few builtin commands can be the "first word".
424
425- Did you misspell a proc name?
426- Are you trying to run an external command? Such commands aren't allowed in
427 pure mode.
428
429## Runtime Errors - Oils and YSH
430
431These errors don't occur in shells like [bash]($xref) and [zsh]($xref).
432
433They may involve Python-like **expressions** and **typed data**.
434
435They're numbered starting from `200`.
436
437### OILS-ERR-200
438
439<!--
440Generated with:
441test/runtime-errors.sh test-external_cmd_typed_args
442-->
443
444```
445 cat ("myfile")
446 ^
447[ -c flag ]:1: fatal: 'cat' appears to be external. External commands don't accept typed args (OILS-ERR-200)
448```
449
450- Builtin commands and user-defined procs may accept [typed
451 args](ref/chap-cmd-lang.html#typed-arg), but external commands never do.
452- Did you misspell a [YSH proc](ref/chap-cmd-lang.html#proc-def)? If a name is
453 not found, YSH assumes it's an external command.
454- Did you forget to source a file that contains the proc or shell function you
455 wanted to run?
456
457### OILS-ERR-201
458
459<!--
460Generated with:
461test/runtime-errors.sh test-arith_ops_str
462-->
463
464```
465 = "age: " + "100"
466 ^
467[ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201)
468
469 = 100 + myvar
470 ^
471[ -c flag ]:2: fatal: Binary operator expected numbers, got Int and Str (OILS-ERR-201)
472```
473
474- Did you mean to use `++` to concatenate strings/lists?
475- The arithmetic operators [can coerce string operands to
476 numbers](ref/chap-expr-lang.html#ysh-arith). However, if you are operating on
477 user provided input, it may be a better idea to first parse that input with
478 [`int()`](ref/chap-builtin-func.html#int) or
479 [`float()`](ref/chap-builtin-func.html#float).
480
481### OILS-ERR-202
482
483<!--
484Generated with:
485test/ysh-runtime-errors.sh test-float-equality
486-->
487
488```
489 pp (42.0 === x)
490 ^~~
491[ -c flag ]:3: fatal: Equality isn't defined on Float values (OILS-ERR-202)
492```
493
494Floating point numbers shouldn't be tested for equality. Alternatives:
495
496 = abs(42.0 - x) < 0.1
497 = floatEquals(42.0, x)
498
499### OILS-ERR-203
500
501<!--
502Generated with:
503test/ysh-runtime-errors.sh test-cannot-stringify-list
504-->
505
506```
507 var mylist = [1,2,3]; write $[mylist]
508 ^~
509[ -c flag ]:1: fatal: Expr sub got a List, which can't be stringified (OILS-ERR-203)
510```
511
512- Did you mean to use `@mylist` instead of `$mylist`?
513- Did you mean to use `@[myfunc()]` instead of `$[myfunc()]`?
514- Did you mean `$[join(mylist)]`?
515
516Or:
517
518- Do you have an element that can't be stringified in a list, like `['good',
519 {bad: true}]`?
520
521### OILS-ERR-204
522
523<!--
524Generated with:
525test/ysh-runtime-errors.sh test-purity
526-->
527
528```
529 x=$(date)
530 ^~
531impure.sh:1: fatal: Command subs aren't allowed in pure mode (OILS-ERR-204)
532```
533
534In **pure mode**, the shell can't do I/O. It's intended for config file
535evaluation and pure functions.
536
537- Did you mean to use `--eval` instead of `--eval-pure`?
538- Did you mean to use a `proc`, rather than a `func`?
539
540
541<!-- TODO -->
542
543## Runtime Errors: `strict:all`
544
545### OILS-ERR-300
546
547```
548 if ! ls | wc -l; then echo failed; fi
549 ^
550[ -c flag ]:1: fatal: Command conditionals should only have one status, not Pipeline (strict_errexit, OILS-ERR-300)
551```
552
553Compound commands can't be used as conditionals because it's ambiguous.
554
555It confuses true/false with pass/fail. What if part of the pipeline fails?
556What if `ls` doesn't exist?
557
558This YSH idiom is more explicit:
559
560 try {
561 ls | wc -l
562 }
563 if failed {
564 echo failed
565 }
566
567### OILS-ERR-301
568
569<!--
570Generated with demo/home-page.sh strict-mode
571-->
572
573```
574 if shell-func; then
575 ^~~~~~~~~~
576foo.sh:9: fatal: Can't run functions or procs while errexit is disabled (OILS-ERR-301)
577```
578
579This error prevents you from hitting a **pitfall** with `set -e` aka `errexit`,
580as it's defined in POSIX shell.
581
582Here are some shell-compatible solutions:
583
584- Rewrite your code to avoid the function call within `if`, `||`, etc.
585- Wrap the function in another process, like `if $0 shell-func`
586 - This is what we call the [$0 Dispatch Pattern](https://www.oilshell.org/blog/2021/08/xargs.html)
587
588In YSH, use the [try][] builtin instead of `if`.
589
590[try]: ref/chap-builtin-cmd.html#try
591
592- [Guide to YSH Error Handling](ysh-error.html)
593- Technical details: [YSH Fixes Shell's Error Handling (`errexit`)](error-handling.html)
594
595### OILS-ERR-302
596
597<!--
598Generated with test/spec.sh strict-options -r 16
599-->
600
601```
602 FOO=bar eval 'echo FOO=$FOO'
603 ^~~~
604[ stdin ]:3: fatal: Special builtins can't have prefix bindings (OILS-ERR-302)
605```
606
607In POSIX shell, prefix bindings have two behaviors:
608
6091. Usually, they set the environment temporarily.
6101. When applied to "special builtins", the bindings persist, and are not
611 exported.
612
613This is invisible and confusing, so YSH has `shopt --set strict_env_binding` to
614make the first meaning the only one.
615
616Try this instead:
617
618 var FOO = 'bar'
619 eval 'echo FOO=$FOO'
620
621## Appendix
622
623### Kinds of Errors from Oils
624
625- Runtime errors (status 1) - the shell tried to do something, but failed.
626 - Example: `echo hi > /does/not/exist`
627- Parse errors and builtin usage errors (status 2) - input rejected, so the
628 shell didn't try to do anything.
629- Uncaught I/O errors (status 2)
630- Expression errors (status 3)
631- User errors from the `error` builtin (status 10 is default)
632
633### Contributors
634
635(If you updated this doc, feel free to add your name to the end of this list.)
636