Skip to main content
Conventions

Errors

The unified error response format, error types, and troubleshooting practices for the Qoder Cloud Agents API.

Error envelope format

The 401 authentication error uses a different response structure from other HTTP error codes. See 401 — Authentication Error for the confirmed format.
KE verification needed: Whether error codes 400, 403, 404, 409, and 500 also use the {"code":"...","message":"...","timestamp":"..."} structure has not been confirmed. The envelope definition below applies to those error codes pending verification.
For error codes other than 401, error responses follow this JSON structure:
{
  "type": "error",
  "error": {
    "type": "<error_type>",
    "message": "<human-readable error description>",
    "param": "<name of the request parameter that triggered the error (optional)>"
  }
}

Field descriptions

FieldTypeRequiredDescription
typestringYesAlways"error"
error.typestringYesError type identifier
error.messagestringYesHuman-readable error description
error.paramstringNoName of the request parameter that triggered the error

Error types overview

HTTP status codeError identifierDescription
400error.type:invalid_request_errorInvalid or missing request parameters
401code:TOKEN_INVALIDAuthentication failed; the token is invalid or missing
403error.type:permission_errorAuthentication succeeded but access to the target resource is denied
404error.type:not_found_errorThe target resource does not exist
409error.type:conflict_errorResource state conflict (for example, duplicate creation)
500error.type:api_errorInternal server error

Error type details

400 — invalid_request_error

The request format or parameters are invalid. Common triggers:
  • Missing required field (for example, name)
  • Incorrect field value type (for example, a number provided where a string is expected)
  • Request body exceeds the 4 MB size limit
  • Malformed JSON
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "Missing required field: name",
    "param": "name"
  }
}
# Trigger example: missing the name field
curl -X POST "https://api.qoder.com.cn/api/v1/cloud/agents" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{}'

401 — Authentication Error

Authentication failed. Common triggers:
  • No Authorization header provided
  • Malformed PAT format
  • Expired or revoked PAT
  • Using x-api-key instead of a Bearer Token
{
  "code": "TOKEN_INVALID",
  "message": "invalid pt-token",
  "timestamp": "1782950157223"
}
# Trigger example: using an invalid token
curl -s "https://api.qoder.com.cn/api/v1/cloud/agents" \
  -H "Authorization: Bearer pt-invalid-token"

403 — permission_error

Authentication succeeded but you do not have the required permissions. Common triggers:
  • The PAT has no access to the target Agent (it belongs to another user or organization)
  • The PAT's permission scope does not cover the current operation
  • Attempting to operate on an archived and locked resource
{
  "type": "error",
  "error": {
    "type": "permission_error",
    "message": "You do not have permission to access this agent."
  }
}
# Trigger example: accessing another user's Agent
curl -s "https://api.qoder.com.cn/api/v1/cloud/agents/agent_other_user_123" \
  -H "Authorization: Bearer $QODER_PAT"

404 — not_found_error

The target resource does not exist. Common triggers:
  • Agent/Session/Environment ID does not exist
  • Resource has been deleted
  • Typo in the URL path
{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "Agent not found: agent_nonexistent_123"
  }
}
# Trigger example: querying a non-existent Agent
curl -s "https://api.qoder.com.cn/api/v1/cloud/agents/agent_nonexistent_123" \
  -H "Authorization: Bearer $QODER_PAT"

409 — conflict_error

Resource state conflict; the operation cannot be executed. Common triggers:
  • A repeated request using the same idempotency key but a different request body
  • Attempting to continue operating on an already-terminated Session
  • Attempting to create a resource with a name that already exists
{
  "type": "error",
  "error": {
    "type": "conflict_error",
    "message": "A request with this idempotency key has already been processed with different parameters."
  }
}

500 — api_error

Internal server error. Common triggers:
  • Service temporarily unavailable
  • Internal component exception
  • Database connection timeout
{
  "type": "error",
  "error": {
    "type": "api_error",
    "message": "An internal error occurred. Please try again later."
  }
}
When a 500 error occurs, use an exponential backoff strategy for retries (wait 1s → 2s → 4s).

Error handling best practices

  • Parse the error identifier for programmatic error handling rather than relying solely on HTTP status codes. For 401 errors, parse the code field; for all other errors, parse error.type.
  • Logerror.message for troubleshooting.
  • Checkerror.param to quickly locate the problematic field.
  • Do not retry 4xx errors (unless you have modified the request parameters).
  • Use backoff retry for 5xx errors (maximum 3 retries).
# Example request with error handling
response=$(curl -s -w "\n%{http_code}" \
  "https://api.qoder.com.cn/api/v1/cloud/agents" \
  -H "Authorization: Bearer $QODER_PAT")

# Extract HTTP status code
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" -ge 400 ]; then
  if [ "$http_code" -eq 401 ]; then
    # 401 uses the 'code' field; 'error.type' is not present
    error_code=$(echo "$body" | python3 -c "import sys,json; print(json.load(sys.stdin)['code'])")
    echo "Authentication error: $error_code"
  else
    error_type=$(echo "$body" | python3 -c "import sys,json; print(json.load(sys.stdin)['error']['type'])")
    echo "API error: $error_type"
  fi
fi
Guides
Tutorials
API Reference