Skip to content
Latest stable: v0.8.0.

Config Reference

interface ChaosConfig {
schemaVersion?: 1;
network?: NetworkConfig;
ui?: UiConfig;
websocket?: WebSocketConfig;
sse?: SSEConfig;
groups?: RuleGroupConfig[];
presets?: string[];
customPresets?: Record<string, PresetConfigSlice>;
seed?: number;
debug?: boolean | { enabled: boolean };
profile?: string;
profileOverrides?: ProfileOverrideSlice;
customProfiles?: Record<string, ProfileConfigSlice>;
matchers?: Record<string, NamedMatcher>;
}

schemaVersion is reserved for forward-compatibility. Default is 1; unknown values reject with code: 'unknown_schema_version'. See Rule Validation.

seed controls probability-driven chaos decisions. The same seed plus the same interaction sequence produces the same normalized event sequence.

debug toggles Debug Mode - every rule decision emits a type: 'debug' event and mirrors a [Chaos] ... line to console.debug. Off by default; framework-agnostic, so it does not interact with Playwright’s PWDEBUG, Cypress’s --browser debugger, Puppeteer’s devtools: true, or WDIO’s logLevel.

profile, profileOverrides, and customProfiles drive scenario profile resolution. The full surface lives on Scenario profiles; the field shapes are:

type ProfileConfigSlice = Omit<
ChaosConfig,
'customPresets' | 'customProfiles' | 'profile' | 'profileOverrides' | 'schemaVersion'
>;
type ProfileOverrideSlice = ProfileConfigSlice;
interface Profile {
readonly name: string;
readonly config: ProfileConfigSlice;
}

Scalar precedence (highest wins): profileOverrides.{seed,debug} > top-level {seed,debug} > the profile’s own {seed,debug}. Rule arrays append in the order: profile rules, top-level rules, override rules.

interface NetworkConfig {
failures?: NetworkFailureConfig[];
latencies?: NetworkLatencyConfig[];
aborts?: NetworkAbortConfig[];
corruptions?: NetworkCorruptionConfig[];
cors?: NetworkCorsConfig[];
}

Each network rule supports urlPattern, optional methods, probability, optional request counting, optional GraphQL operation matching, plus the advanced matcher fields.

interface RequestCountingOptions {
onNth?: number;
everyNth?: number;
afterN?: number;
}
type HostnameMatcher = string | RegExp;
type RequestKvMatcher = string | RegExp | boolean;
type RequestResourceType = 'fetch' | 'xhr';
interface NetworkRuleMatchers {
urlPattern?: string;
methods?: string[];
graphqlOperation?: string | RegExp;
hostname?: HostnameMatcher;
queryParams?: Record<string, RequestKvMatcher>;
requestHeaders?: Record<string, RequestKvMatcher>;
resourceTypes?: RequestResourceType[];
matcher?: string;
}

A rule MUST use either a matcher reference (with no inline matcher fields) OR one or more inline matcher fields - never both. Mixing surfaces matcher_inline_conflict at validation time.

graphqlOperation is an additional matcher. It matches an operationName field, a named query / mutation / subscription, or a persisted-query GET parameter. Anonymous operations do not match a non-null matcher. If a request body cannot be parsed for GraphQL operation detection (for example multipart, streaming, or XHR Blob bodies), Chaos Maker emits a diagnostic event with reason: 'graphql-body-unparseable' and applied: false.

requestHeaders matches against the request’s headers (key comparison case-insensitive). The field is named requestHeaders (not headers) so it does not collide with the response-synthesis headers field on NetworkFailureConfig. string, RegExp, true, and false value matchers carry the same semantics as queryParams.

resourceTypes is a non-empty subset of 'fetch' | 'xhr'. WebSocket and SSE rules already live in their own categories and are not addressable here.

interface NamedMatcher {
urlPattern?: string;
methods?: string[];
graphqlOperation?: string | RegExp;
hostname?: HostnameMatcher;
queryParams?: Record<string, RequestKvMatcher>;
requestHeaders?: Record<string, RequestKvMatcher>;
resourceTypes?: RequestResourceType[];
}

The top-level matchers registry holds reusable NamedMatcher entries. Rules reference one via matcher: 'name'. The resolver runs after preset and profile expansion, inlines the registered fields, and strips both the matcher reference and the matchers registry from the resolved config. See Advanced matchers for the full surface, including the four issue codes (matcher_not_found, matcher_collision, matcher_inline_conflict, matcher_cycle).

Three matchers are built in and resolve by name with no matchers entry: graphql (urlPattern: '/graphql'), apiRequests (urlPattern: '/api'), and authRequests (requestHeaders: { authorization: true }). A matchers entry that reuses one of these names overrides it. authRequests is a network-only matcher; see Advanced matchers for built-in behavior across transports.

interface UiConfig {
assaults?: UiAssaultConfig[];
}
interface UiAssaultConfig {
selector: string;
action: 'disable' | 'hide' | 'remove';
probability: number;
}
interface WebSocketConfig {
drops?: WebSocketDropConfig[];
delays?: WebSocketDelayConfig[];
corruptions?: WebSocketCorruptConfig[];
closes?: WebSocketCloseConfig[];
}
type WebSocketDirection = 'inbound' | 'outbound' | 'both';
type WebSocketCorruptionStrategy = 'truncate' | 'malformed-json' | 'empty' | 'wrong-type';

Every WebSocket rule type is a discriminated union of two shapes:

type TransportRuleMatchers =
| {
urlPattern?: string;
hostname?: HostnameMatcher;
queryParams?: Record<string, RequestKvMatcher>;
}
| {
matcher: string;
};

A rule sets either inline targeting (any combination of urlPattern, hostname, and queryParams) or a matcher: 'name' reference into the top-level matcher registry, never both. urlPattern is optional as long as hostname or queryParams is present, matching the network rule surface. Mixing inline fields with matcher surfaces matcher_inline_conflict. Omitting both surfaces the existing matcher_inline_conflict “rule must set either matcher reference or at least one matcher field” issue. The transport-irrelevant fields from NamedMatcher (methods, requestHeaders, resourceTypes, graphqlOperation) are rejected if inlined and silently ignored when carried by a referenced matcher so one matcher can target network, WebSocket, and SSE without duplication. See Advanced matchers for the full semantics.

interface SSEConfig {
drops?: SSEDropConfig[];
delays?: SSEDelayConfig[];
corruptions?: SSECorruptConfig[];
closes?: SSECloseConfig[];
}
type SSEEventTypeMatcher = string | '*';
type SSECorruptionStrategy = 'truncate' | 'malformed-json' | 'empty' | 'wrong-type';

Drop, delay, and corruption rules accept optional eventType. The default is message; use a named event like token or the '*' wildcard for all data events.

Every SSE rule type uses the same TransportRuleMatchers discriminated union as WebSocket rules: either inline targeting (urlPattern, hostname, queryParams) or a matcher: 'name' reference. The validation guarantees, debug attribution, and silent-ignore semantics for transport-irrelevant matcher fields match the WebSocket surface.

interface ChaosEvent {
type: ChaosEventType;
timestamp: number;
applied: boolean;
detail: Record<string, unknown>;
}

Use applied to distinguish “matched and rolled false” from “chaos actually changed browser behavior”. sse:drop, sse:delay, and sse:corrupt events include detail.eventType; sse:close includes detail.reason instead. GraphQL-aware network events include detail.operationName when one was identified.