SC2155: Declare and Assign Separately to Preserve Exit Codes
Avoid masking command failures in bash by separating local variable declaration from assignment. Fix SC2155 for reliable error detection.
Detailed Explanation
The Hidden Bug in local var=$(command)
When you combine local (or export, declare) with a command
substitution, the exit status of the command is replaced by the exit
status of the local keyword — which is almost always 0 (success).
The Problem
my_function() {
local result=$(failing_command) # Exit code is MASKED
echo "Result: $result" # Runs even if command failed!
}
Even with set -e, the script will NOT exit because local returns 0:
set -e
my_function() {
local output=$(false) # false returns 1, but local returns 0
echo "This runs!" # Still executes
}
my_function
The Fix
Declare and assign on separate lines:
my_function() {
local result
result=$(failing_command) # Exit code is preserved
echo "Result: $result" # Only runs on success (with set -e)
}
Same Issue with export and declare
# BAD: exit code masked
export PATH=$(build_path)
declare -r CONFIG=$(load_config)
# GOOD: separate declaration and assignment
export PATH
PATH=$(build_path)
declare -r CONFIG
CONFIG=$(load_config)
When It Doesn't Matter
If the command cannot fail, or you don't care about its exit status, combining is acceptable (though the linter will still flag it):
local timestamp=$(date +%s) # date rarely fails
local hostname=$(hostname) # also unlikely to fail
Best Practice
Always separate declaration and assignment in functions. It costs nothing and prevents a class of hard-to-debug issues where failures are silently ignored.
Use Case
Bash functions that call external commands and need reliable error detection. Common in library scripts, error-handling wrappers, and any function where the return value of a command determines control flow.
Try It — Shell Script Linter
Related Topics
Bash Strict Mode: set -euo pipefail Explained
Script Setup
SC2164: cd Without Error Handling in Shell Scripts
Error Handling
SC2154: Referenced but Not Assigned Variables in Shell Scripts
ShellCheck Patterns
SC2115: Dangerous rm -rf with Unguarded Variables
Error Handling
SC2046: Unquoted Command Substitution
Quoting