Error Handling
The Error Model
Section titled “The Error Model”Every lash error has two parts:
- Problem: A plain-English description of what went wrong.
- Suggestion: An actionable step to fix it.
This applies to all errors: command failures, type mismatches, method errors, and syntax problems.
Error Formats
Section titled “Error Formats”lash supports three output formats, controlled by the LASH_ERROR_FORMAT environment variable or the --error-format CLI flag.
Human (default)
Section titled “Human (default)”Clear, conversational messages with source location and suggestion:
`lss -la`.sort() ^^^^^^^^ Command 'lss' not found (exit code 127). Did you mean 'ls'? Check your spelling or install the program.Single-line compact JSON to stderr, one line per error. Useful for tool integration:
{"type":"cmd_err","expr":"`lss -la`.sort()","step":"lss -la","code":127,"problem":"command not found","suggest":["ls","less"]}Token-optimized terse format for LLM consumption:
ERR cmd `lss` !found 127 ?ls ?lessSetting the Format
Section titled “Setting the Format”# via environment variableexport LASH_ERROR_FORMAT=jsonlash script.lash
# via CLI flaglash --error-format json script.lashChain Error Pinpointing
Section titled “Chain Error Pinpointing”When a functional chain fails, lash identifies the exact step that caused the failure, not just the whole expression:
`cat data.txt`.sort().map(x => x.toNumber()).sum()If toNumber() fails on a non-numeric line, the error points to the .map(x => x.toNumber()) step, showing the input data and expected vs actual types.
Did-You-Mean Suggestions
Section titled “Did-You-Mean Suggestions”lash uses Levenshtein distance to suggest corrections for misspelled commands and method names.
Command typos:
$ gti statusCommand 'gti' not found.Did you mean 'git'?In interactive mode, suggestions appear as a navigable list:
| Key | Action |
|---|---|
| Up/Down | Navigate suggestions, updating prompt |
| 1-9 | Jump to numbered suggestion |
| Enter | Submit selected suggestion |
| Escape | Dismiss suggestions |
| Any other | Dismiss suggestions, type that character |
Arguments from the original command are preserved in suggestions.
Method typos:
`ls`.srot()# Error: unknown method 'srot'. Did you mean 'sort'?Permission Errors
Section titled “Permission Errors”Instead of a raw “Permission Denied,” lash explains which file is restricted and suggests using elevated privileges:
Cannot read '/etc/shadow': permission denied.Try running with elevated privileges or check file permissions with 'ls -la /etc/shadow'.Exit Codes
Section titled “Exit Codes”The $? variable holds the exit code of the last command:
grep "pattern" file.txtecho "exit code: $?" # 0 if found, 1 if not found
`curl -f https://example.com/api`.captureif $? != 0 { echo "request failed"}In functional chains, the exit code reflects the chain outcome. A failed chain step sets a non-zero exit code.
Practical Error Handling
Section titled “Practical Error Handling”Since lash does not have try/catch, use exit codes and .isSuccess/.isFailure to handle errors:
let result = `make -j8`.captureif result.isFailure { echo "build failed:" (result["stderr"]) exit 1}
echo "build succeeded"Check command existence before running:
let check = `which docker`.captureif check.isFailure { exit "docker is not installed"}