A bare string in the pattern
The rule is created and never fires
pattern:
{ "source": "aws.s3" }
event:
{ "source": "aws.s3", "detail-type": "Object Created" }Match a pattern against an event without creating a rule and waiting to see whether anything arrives. The matching runs here, in your browser.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Test. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
The rule is created and never fires
pattern:
{ "source": "aws.s3" }
event:
{ "source": "aws.s3", "detail-type": "Object Created" }Every named key found, and the rest of the event ignored
pattern:
{ "source": ["aws.s3"], "detail": { "object": { "key": [{ "suffix": ".pdf" }] } } }
event:
{ "source": "aws.s3", "detail-type": "Object Created", "detail": { "object": { "key": "uploads/report.pdf", "size": 4096 } } }The exact place they disagree, rather than a rule that stays silent
pattern:
{ "source": ["aws.s3"], "detail": { "object": { "size": [{ "numeric": [">", 8192] }] } } }
event:
{ "source": "aws.s3", "detail": { "object": { "size": 4096 } } }These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Every leaf in an event pattern is an array of alternatives, so a bare string matches nothing and the rule is created without complaint.
Instead:Wrap it: "source": ["aws.s3"].
Matching is exact. There is no case folding and no partial matching.
Instead:Use equals-ignore-case, or prefix and wildcard where the value is not under your control.
Each leaf takes one list of alternatives, and two filters in the array are alternatives rather than requirements, so either one matching is enough.
Instead:Write both bounds in one filter: { "numeric": [">=", 100, "<", 200] }.
Every value in an event pattern is a list of alternatives, so "detail-type": "Object Created" matches nothing while "detail-type": ["Object Created"] matches. The rule is created either way, and it simply never fires.
There is no error, no metric that distinguishes it from a quiet event bus, and the rule looks correct in the console. The only signal is that the target is never invoked.
That is the model: a pattern is a subset the event has to satisfy, not a shape it has to equal. So a narrow pattern is narrow because of what it names, not because of what it leaves out.
There is no partial matching. A pattern that works today stops matching silently if a producer changes the case of a value or adds a prefix, which is what prefix, wildcard and equals-ignore-case exist for.
So resources: ["arn:aws:s3:::my-bucket"] in a pattern matches an event whose resources array contains that value among others. The same applies to an object sub-pattern against an array of objects.
Which is how you exclude a whole namespace rather than a list of values. numeric takes pairs of an operator and a number, and every pair has to hold, so a range is written as one filter rather than two.
It works on leaf nodes, and exists: false is the way to match events that do not carry an optional attribute. Everything else requires the field to be there before it can compare anything.