This loop only ever runs once — check the list expression
`for x in "$onething"` iterates a single fixed value. SC2043 flags for-loops whose list clearly has just one item.
Problem
A `for` loop whose word list is a single quoted string, a single variable known to hold one value, or a literal with no expansion at all will only ever execute its body once. This is frequently a sign that the author meant to iterate over multiple items — an array, a list of files, or the positional parameters — but wrote something that evaluates to just one value. It is not necessarily a bug (sometimes a one-shot "loop" is used deliberately so `break`/`continue` can be reused), but in most reported cases it indicates a missing `$@`, missing array expansion, or a typo.
Bad
name="single value"
for x in "$name"; do
process "$x"
doneGood
names=("first value" "second value")
for x in "${names[@]}"; do
process "$x"
doneExplanation
Once the list expression genuinely contains multiple words — an unquoted glob, `"$@"`, or `"${array[@]}"` — the loop iterates as expected. If a single-item loop really is intentional (e.g. for early `break` logic), an `if` statement is usually clearer and avoids the warning.
Related
SC2068
SC2066
SC2231
When It Matters
for x in "$list" or for x in $(echo "$one_thing") iterates exactly once, which means the loop is decoration around a single call. Usually the author intended to iterate a list and quoted it into a single word, or built the list in a way that collapsed it. A loop that runs once is not an error, so nothing complains at runtime — the script simply processes the first item and reports success.
Second Example
Note
Brace expansion happens before variable expansion, so {1..$n} does not work — use seq or a C-style loop for a dynamic range.
Exceptions
A single-iteration loop is sometimes a deliberate placeholder for a list that will grow, or a way to get a break target. Both are clearer written as a comment plus straight-line code, or as a while true with an explicit break.
Faq
Q
How do I loop over a dynamic range?
A
for (( i = 1; i <= n; i++ )) in Bash, or for i in $(seq 1 "$n") when you need POSIX compatibility.
Q
Why does {1..$n} print literally?
A
Brace expansion is performed before parameter expansion, so the shell never sees a number there.
Q
How do I iterate the lines of a variable?
A
Feed it to a read loop with a here-string: while IFS= read -r line; do ...; done <<< "$text".