Error Codes
Job results include optional error_code and error_retryable fields for machine-parseable error classification. These are additive — the existing error field (human-readable string) is unchanged.
Response Fields
| Field | Type | Description |
|---|---|---|
error |
string \| null |
Human-readable error message (unchanged) |
error_code |
string \| null |
Machine-parseable error code from the table below |
error_retryable |
bool \| null |
Whether the caller should retry the request |
All three fields are null when the job succeeds without error.
Error Code Reference
| Code | Cause | Retryable | Description |
|---|---|---|---|
CONNECTION_TIMEOUT |
Device unreachable | ✅ | TCP connection timed out. Check host/port, network path, or device availability. |
AUTH_FAILURE |
Bad credentials | ❌ | Device rejected the username/password. Triggers TACACS lockout tracking. |
SSH_ERROR |
SSH protocol failure | ✅ | SSH handshake or key exchange failed. May indicate incompatible SSH versions. |
CONFIG_REJECTED |
Invalid config commands | ❌ | Device rejected one or more configuration commands (syntax error, invalid input). |
CIRCUIT_OPEN |
Too many recent failures | ✅ | Circuit breaker is open for this device due to repeated connection failures. Retry after the breaker resets. |
AUTODETECT_FAILED |
Platform detection failed | ❌ | SSHDetect could not determine the device platform. Specify platform explicitly. |
UNKNOWN |
Unhandled exception | ❌ | An unexpected error occurred in the worker. Check server logs. |
Example Response
{
"job_id": "abc-123",
"status": "finished",
"results": null,
"error": "TCP connection to device failed.\n\nDevice settings: cisco_ios 192.168.1.1:22",
"error_code": "CONNECTION_TIMEOUT",
"error_retryable": true,
"detected_platform": null,
"tags": null
}
Client Library
The Python client raises specific exception subclasses based on error_code:
from naas_client import NaasClient
from naas_client.exceptions import (
NaasJobError, # base — UNKNOWN or unmapped codes
NaasConnectionError, # CONNECTION_TIMEOUT, SSH_ERROR
NaasDeviceAuthError, # AUTH_FAILURE
NaasConfigError, # CONFIG_REJECTED
NaasCircuitOpenError, # CIRCUIT_OPEN
)
with NaasClient("https://naas.example.com", api_key="eyJ...") as client:
job = client.send_command(host="10.0.0.1", platform="cisco_ios", commands=["show version"])
try:
result = job.wait(timeout=30)
except NaasConnectionError as e:
print(f"Device unreachable: {e.error_code}, retry={e.error_retryable}")
except NaasDeviceAuthError:
print("Bad credentials — do not retry")
except NaasJobError as e:
print(f"Other failure: {e.error_code}")
All subclasses extend NaasJobError, so catching NaasJobError still works as a catch-all.
Backward Compatibility
errorfield: unchanged, stillstr | nullerror_code/error_retryable: new optional fields,nullwhen no error- Old jobs in Redis (pre-upgrade): new fields returned as
null - Existing client code catching
NaasJobErrorcontinues to work — subclasses are additive