<@ULVA73B9P> Is it possible for us to create an au...
# ask-marvin
i
@Marvin Is it possible for us to create an automation (prefect v3) which will alert when tag = X and tag != Y. We have an extra tag we add for test flows and do not want to be alerted by these.
đź‘€ 1
m
âś… thought for 182.5 seconds
Yes — but not with the simple tag filter UI alone. In Prefect 3, the built-in Flow Run Tags filter in automations is evaluated with OR logic, so it won’t directly express:
tag = X AND tag != Y
If you want “alert for tag X, except when tag Y is also present”, you’ll want a custom event trigger using
match_related
. Example logic: - include runs with tag
X
- exclude runs with tag
Y
Like this:
Copy code
json
{
  "trigger": {
    "type": "event",
    "expect": ["prefect.flow-run.Failed"],
    "match": {
      "prefect.resource.id": "prefect.flow-run.*"
    },
    "match_related": [
      {
        "prefect.resource.role": "tag",
        "prefect.resource.id": "prefect.tag.X"
      },
      {
        "prefect.resource.role": "tag",
        "prefect.resource.id": "!prefect.tag.Y"
      }
    ]
  }
}
So for your case, if: -
X
= your “real alertable” tag -
Y
= your “test” tag then this will alert only for runs tagged
X
and not tagged
Y
. A few notes: -
match_related
supports negation with
!
- separate entries in
match_related
are effectively combined with AND - this is the right path when the UI tag selector is too limited Relevant docs: - Automations - Advanced matching for related resources If you want, I can help you turn this into: 1. a full automation JSON/YAML, or 2. a Python SDK example for your exact tags.
i
@Marvin we tried this but it did not work, is this a known issue?
m
âś… thought for 163.9 seconds
I don’t see an existing GitHub issue/discussion for this, but based on the implementation, there is a real limitation here. Short version:
match_related
negation does not behave like “NOT EXISTS”
. If you use something like:
Copy code
json
{
  "match_related": [
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.X"
    },
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "!prefect.tag.Y"
    }
  ]
}
that second clause is evaluated against the list of related tag resources by checking whether any related resource matches it. That means: - flow run tags =
["X"]
-> likely works - flow run tags =
["X", "Y"]
-> can still match unexpectedly - flow run tags =
[]
-> won’t match the negation clause at all The key problem is that
!prefect.tag.Y
is not treated as “there is no Y tag present”; it’s treated more like “there exists a related tag whose id is not Y”. So yes: what you hit looks like a real product limitation / semantics issue, even if it’s not currently tracked as a named known bug. Practical implication for your case If a run has both: - your normal tag
X
- your test tag
Y
then the negation clause may still succeed because the
X
tag itself satisfies
!= Y
. So this pattern is not reliable for “include X but exclude Y”. Docs: - Advanced matching for related resources - Automations Recommended workarounds 1. Use a positive-only alert tag Add a tag only to runs you do want alerts for, like
alerting-enabled
, and filter only on that. 2. Use separate naming conventions Exclude test runs by flow/deployment naming if that is stable. 3. Route test flows to a different deployment/workspace/pool Then alert only on the production surface. If you want, I can help you design the best reliable workaround for your setup. Also, since this appears to be a genuine gap and I didn’t find an existing issue/discussion, I can summarize it cleanly for a GitHub discussion if that would be useful.
i
@Marvin How could I create an automation if I were to introduce a new tag "alerting_on" but need also tag X to exist? So I want an automation where tag = X and tag = alerting_on
m
âś… thought for 9.2 seconds
Yes — that pattern should work reliably. If you want:
tag = X AND tag = alerting_on
use
match_related
with two positive tag matches:
Copy code
json
{
  "trigger": {
    "type": "event",
    "expect": ["prefect.flow-run.Failed"],
    "match": {
      "prefect.resource.id": "prefect.flow-run.*"
    },
    "match_related": [
      {
        "prefect.resource.role": "tag",
        "prefect.resource.id": "prefect.tag.X"
      },
      {
        "prefect.resource.role": "tag",
        "prefect.resource.id": "prefect.tag.alerting_on"
      }
    ]
  }
}
That means: - the event must be for a flow run - the flow run must have tag
X
- the flow run must also have tag
alerting_on
This is much safer than trying to do
X AND NOT test
. A few notes: - replace
X
with your real tag name - tag ids are formatted as
prefect.tag.<tag-name>
- multiple entries in
match_related
are effectively combined with AND If you’re creating this in the UI, you may need to use the advanced/custom trigger configuration rather than the simple tag picker. If you want a concrete example, here’s a fuller skeleton:
Copy code
json
{
  "name": "Alert on failed X runs with alerting enabled",
  "trigger": {
    "type": "event",
    "expect": ["prefect.flow-run.Failed"],
    "posture": "Reactive",
    "match": {
      "prefect.resource.id": "prefect.flow-run.*"
    },
    "match_related": [
      {
        "prefect.resource.role": "tag",
        "prefect.resource.id": "prefect.tag.X"
      },
      {
        "prefect.resource.role": "tag",
        "prefect.resource.id": "prefect.tag.alerting_on"
      }
    ]
  },
  "actions": [
    {
      "type": "send-notification"
    }
  ]
}
Docs: - Advanced matching for related resources - Automations If you want, I can help convert this into: - a UI walkthrough, - a Terraform spec, - or a Python SDK automation example.
i
@Marvin we tried creating an automation,
Copy code
{
  "type": "event",
  "match": {
    "prefect.resource.id": "prefect.flow-run.*"
  },
  "match_related": {
    "prefect.resource.id": [
      "prefect.tag.X",
      "prefect.tag.alerting_on"
    ],
    "prefect.resource.role": "tag"
  },
  "after": [],
  "expect": [
    "prefect.flow-run.TimedOut",
    "prefect.flow-run.Crashed"
  ],
  "for_each": [
    "prefect.resource.id"
  ],
  "posture": "Reactive",
  "threshold": 1,
  "within": 0
}
but this will alert if one of the tags is present, so the "AND" does not work
m
âś… thought for 8.2 seconds
Yep — that behavior makes sense with this shape. In your config, you have:
Copy code
json
"match_related": {
  "prefect.resource.id": [
    "prefect.tag.X",
    "prefect.tag.alerting_on"
  ],
  "prefect.resource.role": "tag"
}
That array is treated as OR, not AND. So this means: - match a related resource with role
tag
- whose id is
prefect.tag.X
or
prefect.tag.alerting_on
That’s why either tag alone triggers the automation. To require both tags, you need
match_related
to be a list of separate objects:
Copy code
json
{
  "type": "event",
  "match": {
    "prefect.resource.id": "prefect.flow-run.*"
  },
  "match_related": [
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.X"
    },
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.alerting_on"
    }
  ],
  "after": [],
  "expect": [
    "prefect.flow-run.TimedOut",
    "prefect.flow-run.Crashed"
  ],
  "for_each": [
    "prefect.resource.id"
  ],
  "posture": "Reactive",
  "threshold": 1,
  "within": 0
}
That structure is the important part: - one object with an array of ids -> OR - array of objects -> AND across those conditions So your earlier attempt was very close — it was just using the OR form. Relevant docs: - Advanced matching for related resources If you want, I can also help check whether the UI is rewriting your JSON when you save it, because that can sometimes be the next gotcha.
i
@Marvin in the UI, the automation makes it look like it's a "and" even though it behaves as "or". Just some feedback. Changing it to
Copy code
{
  "type": "event",
  "match": {
    "prefect.resource.id": "prefect.flow-run.*"
  },
  "match_related": [
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.X"
    },
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.alerting_on"
    }
  ],
  "after": [],
  "expect": [
    "prefect.flow-run.TimedOut",
    "prefect.flow-run.Crashed"
  ],
  "for_each": [
    "prefect.resource.id"
  ],
  "posture": "Reactive",
  "threshold": 1,
  "within": 0
}
Works
m
âś… thought for 5.3 seconds
Thanks — that’s very useful feedback, and I agree that UI behavior sounds misleading here. What you observed is consistent with how automations are evaluated: - a single
match_related
object with a list of values for
prefect.resource.id
behaves as OR - a list of separate
match_related
objects behaves as AND So if the UI visually suggests “tag X and alerting_on” while producing the single-object/list-of-values form, that’s definitely confusing. Glad to hear this version works:
Copy code
json
{
  "type": "event",
  "match": {
    "prefect.resource.id": "prefect.flow-run.*"
  },
  "match_related": [
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.X"
    },
    {
      "prefect.resource.role": "tag",
      "prefect.resource.id": "prefect.tag.alerting_on"
    }
  ],
  "after": [],
  "expect": [
    "prefect.flow-run.TimedOut",
    "prefect.flow-run.Crashed"
  ],
  "for_each": [
    "prefect.resource.id"
  ],
  "posture": "Reactive",
  "threshold": 1,
  "within": 0
}
If you’d like, I can turn your finding into a concise GitHub discussion draft, since: - it’s a real UX gotcha - it could help other users - I didn’t find an existing discussion covering this exact confusion