Error format
Shoplazza CLI uses structured JSON error envelopes on stderr for consistent error handling. The envelope is written whenever stderr is not a terminal (piped, redirected, captured by a script) or the output format is json, ndjson, or csv. At an interactive terminal with pretty or table output, the same error prints as a readable Error: line, followed by Code:, Hint:, Request:, and Request ID: lines when available.
Error envelope
An API error:
json
{
"ok": false,
"error": {
"type": "api",
"message": "Product not found",
"detail": {
"status_code": 404,
"request_id": "req_abc123",
"method": "GET",
"path": "/openapi/2026-01/products/999"
}
}
}
A usage error:
json
{
"ok": false,
"error": {
"type": "validation",
"subtype": "unknown_flag",
"message": "unknown flag: --bogus",
"hint": "run the command with --help to list valid flags"
}
}
Error types
| Type | Exit code | Description |
|---|---|---|
api | 1 | Shoplazza API returned an error response (4xx other than 403, or 5xx) |
validation | 2 | Invalid CLI input (unknown or missing flags, bad format) |
auth | 3 | Authentication failure (expired token, missing scope, HTTP 403) |
network | 4 | Network connectivity issue |
internal | 5 | Unexpected CLI error |
A canceled prompt exits with 130 and writes no envelope.
Fields
| Field | Type | Description |
|---|---|---|
ok | boolean | Always false |
error.type | string | One of the 5 error types above |
error.subtype | string | Stable ID for usage errors: unknown_command, unknown_flag, missing_required_flag, invalid_flag_value, invalid_argument, or usage_error (when set) |
error.code | string | Business error code returned by the API (when present) |
error.param | string | The offending flag or parameter (when known) |
error.message | string | Human-readable error description |
error.hint | string | Actionable suggestion for resolving the error (when available) |
error.detail.status_code | number | HTTP status (API errors only) |
error.detail.request_id | string | Request ID for debugging (API errors only) |
error.detail.method, error.detail.path | string | The failing request (API errors only) |
Some commands add command-specific fields to the error object.
Handling errors programmatically
shell
# Capture stderr for error details
output=$(shoplazza products get --params '{"product_id":"999"}' 2>&1)
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "$output" | jq -r '.error.hint'
fi
stdout vs stderr
- stdout — Success data only (JSON envelopes with
"ok": true;--dry-runpreviews and local commands such asauth statusprint their object without the envelope) - stderr — Errors, progress indicators, warnings, and hints
This separation ensures you can safely pipe stdout without corruption:
shell
shoplazza products list --jq '.data.products[].id' | while read id; do
shoplazza products get --params "{\"product_id\":\"$id\"}"
done