Handle validation errors
Provoke every flavor of rejection on purpose and branch on the codes like production code should.
Error handling written against reality: each step provokes one failure mode and asserts the exact error.code your integration should branch on (Errors and Conventions).
Goal
See 400, 404, 409, and both 422 codes in the flesh, each with the envelope fields your logs and UI need.
Prerequisites
$CREDS_BASE,$TOKEN, and a provider whose schema requiresapi_key(scenario 01).
Steps
1. A secret that violates the schema → 422
Create with a wrong secret object (field missing, extras added):
curl -s -X POST "$CREDS_BASE/v1/credentials" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"provider_code": "'$CODE'",
"name": "broken",
"credentials": {"wrong_field": "x"}
}'
Expected 422, error.code = "CREDENTIAL_SCHEMA_VALIDATION_FAILED"; error.details.errors points at the offending fields without echoing your values (Provider Schemas). A malformed configuration fails the same way as CONFIGURATION_SCHEMA_VALIDATION_FAILED.
2. An unknown body field → 400
Send a well-formed create plus one field the contract does not know ("note": "hi"). Expected 400 INVALID_REQUEST — unknown fields are rejected, never silently dropped.
3. A provider that does not exist → 404
Create against no_such_provider. Expected 404 PROVIDER_NOT_FOUND — and remember the same code covers providers your role cannot see.
4. A stale version → 409
Create a valid credential, then PATCH it twice with the same version:
first = httpx.patch(url, headers=headers, json={"name": "renamed", "version": 1})
assert first.status_code == 200
second = httpx.patch(url, headers=headers, json={"name": "again", "version": 1})
assert second.status_code == 409
assert second.json()["error"]["code"] == "CREDENTIAL_VERSION_CONFLICT"
Expected: the second write loses cleanly — re-read for the fresh version, then retry (Defaults and Lifecycle).
5. The envelope is always the same
Every failure above carried error.code, error.message, error.details, error.correlation_id. Branch on the code; log the correlation id; show your own words to users. The full code table: Error Codes.
Verified by the test test_s10_handle_validation_errors.