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

586 lines, 413 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/oilshell/oil/_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 (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## Runtime Errors - Traditional Shell
276
277These errors may occur in shells like [bash]($xref) and [zsh]($xref).
278
279They're numbered starting from `100`. (If we have more than 90 parse errors,
280we can start a new section, like `300`.)
281
282### OILS-ERR-100
283
284<!--
285Generated with:
286test/runtime-errors.sh test-command-not-found
287-->
288
289```
290 findz
291 ^~~~~
292[ -c flag ]:1: Command 'findz' not found (OILS-ERR-100)
293```
294
295The shell tried to execute an external command, but couldn't.
296
297- Did you misspell a command name?
298- Did you misspell a shell function or a YSH `proc`?
299- Is the file in your `$PATH`? The `PATH` variable is a colon-separated list
300 of directories, where executable files may live.
301- Is `findz` file executable bit set? (`chmod +x`)
302
303### OILS-ERR-101
304
305<!--
306Generated with:
307test/runtime-errors.sh test-assoc-array
308-->
309
310Let's look at **three** instances of this error.
311
312```
313 declare -A assoc; assoc[x]=1
314 ^~~~~~
315[ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101)
316```
317
318- Is `x` a string? Then add quotes: `assoc['x']=1`
319- Is `x` a variable? Then write: `assoc[$x]=1`
320
321---
322
323Same idea here:
324
325```
326 declare -A assoc; echo ${assoc[x]}
327 ^
328[ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101)
329```
330
331- Is `x` a string? Then add quotes: `${assoc['x']}`
332- Is `x` a variable? Then write: `${assoc[$x]}`
333
334---
335
336The third example is **tricky** because `unset` takes a **string**. There's an
337extra level of parsing, which:
338
339- Implies an extra level of quoting
340- Causes OSH to display the following **nested** error message
341
342```
343 assoc[k]
344 ^
345[ dynamic LHS word at line 1 of [ -c flag ] ]:1
346
347 declare -A assoc; key=k; unset "assoc[$key]"
348 ^
349[ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101)
350```
351
352To fix it, consider using **single quotes**:
353
354 unset 'assoc[$key]'
355
356---
357
358- This is the error in [Parsing Bash is
359 Undecidable](https://www.oilshell.org/blog/2016/10/20.html) (2016)
360- Also mentioned in [Known Differences](known-differences.html)
361
362
363### OILS-ERR-102
364
365```
366 var cmd = ^(seq 3)
367 ^~~
368[ stdin ]:1: Command 'seq' not found in pure mode (OILS-ERR-102)
369```
370
371The shell tried to execute a command in pure mode, but couldn't.
372
373In pure mode, only user-defined procs and a few builtin commands can be the "first word".
374
375- Did you misspell a proc name?
376- Are you trying to run an external command? Such commands aren't allowed in
377 pure mode.
378
379## Runtime Errors - Oils and YSH
380
381These errors don't occur in shells like [bash]($xref) and [zsh]($xref).
382
383They may involve Python-like **expressions** and **typed data**.
384
385They're numbered starting from `200`.
386
387### OILS-ERR-200
388
389<!--
390Generated with:
391test/runtime-errors.sh test-external_cmd_typed_args
392-->
393
394```
395 cat ("myfile")
396 ^
397[ -c flag ]:1: fatal: 'cat' appears to be external. External commands don't accept typed args (OILS-ERR-200)
398```
399
400- Builtin commands and user-defined procs may accept [typed
401 args](ref/chap-cmd-lang.html#typed-arg), but external commands never do.
402- Did you misspell a [YSH proc](ref/chap-cmd-lang.html#proc-def)? If a name is
403 not found, YSH assumes it's an external command.
404- Did you forget to source a file that contains the proc or shell function you
405 wanted to run?
406
407### OILS-ERR-201
408
409<!--
410Generated with:
411test/runtime-errors.sh test-arith_ops_str
412-->
413
414```
415 = "age: " + "100"
416 ^
417[ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201)
418
419 = 100 + myvar
420 ^
421[ -c flag ]:2: fatal: Binary operator expected numbers, got Int and Str (OILS-ERR-201)
422```
423
424- Did you mean to use `++` to concatenate strings/lists?
425- The arithmetic operators [can coerce string operands to
426 numbers](ref/chap-expr-lang.html#ysh-arith). However, if you are operating on
427 user provided input, it may be a better idea to first parse that input with
428 [`int()`](ref/chap-builtin-func.html#int) or
429 [`float()`](ref/chap-builtin-func.html#float).
430
431### OILS-ERR-202
432
433<!--
434Generated with:
435test/ysh-runtime-errors.sh test-float-equality
436-->
437
438```
439 pp (42.0 === x)
440 ^~~
441[ -c flag ]:3: fatal: Equality isn't defined on Float values (OILS-ERR-202)
442```
443
444Floating point numbers shouldn't be tested for equality. Alternatives:
445
446 = abs(42.0 - x) < 0.1
447 = floatEquals(42.0, x)
448
449### OILS-ERR-203
450
451<!--
452Generated with:
453test/ysh-runtime-errors.sh test-cannot-stringify-list
454-->
455
456```
457 var mylist = [1,2,3]; write $[mylist]
458 ^~
459[ -c flag ]:1: fatal: Expr sub got a List, which can't be stringified (OILS-ERR-203)
460```
461
462- Did you mean to use `@mylist` instead of `$mylist`?
463- Did you mean to use `@[myfunc()]` instead of `$[myfunc()]`?
464- Did you mean `$[join(mylist)]`?
465
466Or:
467
468- Do you have an element that can't be stringified in a list, like `['good',
469 {bad: true}]`?
470
471### OILS-ERR-204
472
473<!--
474Generated with:
475test/ysh-runtime-errors.sh test-purity
476-->
477
478```
479 x=$(date)
480 ^~
481impure.sh:1: fatal: Command subs aren't allowed in pure mode (OILS-ERR-204)
482```
483
484In **pure mode**, the shell can't do I/O. It's intended for config file
485evaluation and pure functions.
486
487- Did you mean to use `--eval` instead of `--eval-pure`?
488- Did you mean to use a `proc`, rather than a `func`?
489
490
491<!-- TODO -->
492
493## Runtime Errors: `strict:all`
494
495### OILS-ERR-300
496
497```
498 if ! ls | wc -l; then echo failed; fi
499 ^
500[ -c flag ]:1: fatal: Command conditionals should only have one status, not Pipeline (strict_errexit, OILS-ERR-300)
501```
502
503Compound commands can't be used as conditionals because it's ambiguous.
504
505It confuses true/false with pass/fail. What if part of the pipeline fails?
506What if `ls` doesn't exist?
507
508This YSH idiom is more explicit:
509
510 try {
511 ls | wc -l
512 }
513 if failed {
514 echo failed
515 }
516
517### OILS-ERR-301
518
519<!--
520Generated with demo/home-page.sh strict-mode
521-->
522
523```
524 if shell-func; then
525 ^~~~~~~~~~
526foo.sh:9: fatal: Can't run functions or procs while errexit is disabled (OILS-ERR-301)
527```
528
529This error prevents you from hitting a **pitfall** with `set -e` aka `errexit`,
530as it's defined in POSIX shell.
531
532Here are some shell-compatible solutions:
533
534- Rewrite your code to avoid the function call within `if`, `||`, etc.
535- Wrap the function in another process, like `if $0 shell-func`
536 - This is what we call the [$0 Dispatch Pattern](https://www.oilshell.org/blog/2021/08/xargs.html)
537
538In YSH, use the [try][] builtin instead of `if`.
539
540[try]: ref/chap-builtin-cmd.html#try
541
542- [Guide to YSH Error Handling](ysh-error.html)
543- Technical details: [YSH Fixes Shell's Error Handling (`errexit`)](error-handling.html)
544
545### OILS-ERR-302
546
547<!--
548Generated with test/spec.sh strict-options -r 16
549-->
550
551```
552 FOO=bar eval 'echo FOO=$FOO'
553 ^~~~
554[ stdin ]:3: fatal: Special builtins can't have prefix bindings (OILS-ERR-302)
555```
556
557In POSIX shell, prefix bindings have two behaviors:
558
5591. Usually, they set the environment temporarily.
5601. When applied to "special builtins", the bindings persist, and are not
561 exported.
562
563This is invisible and confusing, so YSH has `shopt --set strict_env_binding` to
564make the first meaning the only one.
565
566Try this instead:
567
568 var FOO = 'bar'
569 eval 'echo FOO=$FOO'
570
571## Appendix
572
573### Kinds of Errors from Oils
574
575- Runtime errors (status 1) - the shell tried to do something, but failed.
576 - Example: `echo hi > /does/not/exist`
577- Parse errors and builtin usage errors (status 2) - input rejected, so the
578 shell didn't try to do anything.
579- Uncaught I/O errors (status 2)
580- Expression errors (status 3)
581- User errors from the `error` builtin (status 10 is default)
582
583### Contributors
584
585(If you updated this doc, feel free to add your name to the end of this list.)
586