jq // : The Alternative (Default) Operator
jq a // b evaluates to a unless a is null, false, or empty, in which case it falls back to b.
Optional API fields are everywhere; the // operator supplies a default so a missing key does not break a later filter in CI.
What it does
The // operator returns the left-hand outputs that are not null and not false. If the left side produces no such value (null, false, or empty), it produces the right-hand value instead. It is the idiomatic way to default a field.
Common usage
# default a missing field
jq '.description // "no description"' repo.json
# default before arithmetic so null does not break it
jq '[.[] | (.size // 0)] | add' files.json
# chain fallbacks
jq '.name // .login // "unknown"' user.jsonOperators
| Form | What it does |
|---|---|
| a // b | b when a is null, false, or empty |
| (.x // 0) | Default a numeric field |
| .a // .b // c | Chain of fallbacks |
| f? | Run f but suppress errors (try f); emits nothing on error |
| (f)? // d | Default even when f errors (with ?) |
In CI
Default fields with // before feeding them to add, comparisons, or string functions, since those error on null. The related ? postfix (try f) instead suppresses an error and emits nothing, so .a? tolerates a non-object and .[]? a non-array; reach for // when you want a concrete default rather than silence. Mind precedence: // binds loosely, so parenthesize when mixing with the pipe, as in (.a | f) // d.
Common errors in CI
A surprising result usually comes from precedence: .a // .b | f applies f to the whole alternative, not just .b. Parenthesize to disambiguate. Note // also swallows false, so for a boolean field that is legitimately false, test with has() instead of //.