chaos, in a scenario with an INJECT_FAULT step, or from a coding agent with arm_fault.
HTTP faults
Delays compose: a
latency fault on top of an error delays the error. Every delay is capped at 60 seconds.
Error bodies
A status alone proves your retry and error branches run. A client that switches on the provider’s error body, acode, a decline_code, a validation list, needs the body too. An error fault answers with one, sourced in this order and never invented:
- The body you armed.
chaos --body,bodyon anINJECT_FAULTstep, orbodyonarm_fault.headersadds response headers the same way. - The recorded response.
reproduceputs the incident’s recorded body on the armed fault, redacted the way it reached disk. - The spec’s declared example for that exact status on that operation.
- Nothing. No content type, no body, exactly as before.
--body @decline.json reads it from a file. A body must be a JSON object or array, and only an error fault carries one. x-pikopod-fault-applied is unchanged.
Webhook faults
These match on the event (--event, default any) rather than on a method and path.
Virtual versus real time
By default every delay is virtualized: the response is instant and carriesx-pikopod-fault-delay-ms with the delay it represents. That is what scenario check measures, and it is why a 30-second timeout scenario finishes in milliseconds. hang, slow_body, connection_reset, empty_response, random_data_then_close, malformed_response and wrong_content_length are transport-level lies and only act on the real wire.
To put delays and hangs on the wire for your own tests, arm with --wallclock, or start the server with pikopod up --wallclock-faults.
Probability and windows
Every response that a fault touched carries
x-pikopod-fault-applied, which is what the execution.faultApplied assertion reads.
Listing and clearing
--clear with no method and path clears every fault, including webhook faults. mode clear also clears every fault. See pikopod chaos.