<@ULVA73B9P> I'm trying to create automations prog...
# ask-marvin
m
@Marvin I'm trying to create automations programmatically. Specifically, one that emails a group of people when failures happen in deployments/flows with a specific combination of tags. I've created an example automation in Prefect Cloud, using the send-email-notification action. I'm trying to look at the definition from the CLI (via "prefect automations ls", but am getting validation errors: "(data-exception-report-subscriptions) PS D:\source\data_exception_report_subscriptions> prefect automation ls Traceback (most recent call last): File "D:\source\data_exception_report_subscriptions\.venv\Lib\site-packages\prefect\cli\_utilities.py", line 37, in async_wrapper return await fn(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\source\data_exception_report_subscriptions\.venv\Lib\site-packages\prefect\cli\automation.py", line 40, in ls automations = await client.read_automations() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\source\data_exception_report_subscriptions\.venv\Lib\site-packages\prefect\client\orchestration\_automations\client.py", line 204, in read_automations return Automation.model_validate_list(response.json()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\source\data_exception_report_subscriptions\.venv\Lib\site-packages\prefect\_internal\schemas\bases.py", line 64, in model_validate_list return validate_list(cls, obj) ^^^^^^^^^^^^^^^^^^^^^^^ File "D:\source\data_exception_report_subscriptions\.venv\Lib\site-packages\prefect\utilities\generics.py", line 18, in validate_list return [model.model_validate(item) for item in ListValidator.validate_python(input)] ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\source\data_exception_report_subscriptions\.venv\Lib\site-packages\pydantic\main.py", line 627, in model_validate return cls.__pydantic_validator__.validate_python( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pydantic_core._pydantic_core.ValidationError: 18 validation errors for Automation actions.0.DoNothing.type Input should be 'do-nothing' [type=literal_error, input_value='send-email-notification', input_type=str] For further information visit https://errors.pydantic.dev/2.10/v/literal_error actions.0.function-after[selected_deployment_requires_id(), RunDeployment].type Input should be 'run-deployment' [type=literal_error, input_value='send-email-notification', input_type=str] For further information visit https://errors.pydantic.dev/2.10/v/literal_error actions.0.function-after[selected_deployment_requires_id(), PauseDeployment].type Input should be 'pause-deployment' [type=literal_error, input_value='send-email-notification', input_type=str] For further information visit https://errors.pydantic.dev/2.10/v/literal_error actions.0.function-after[selected_deployment_requires_id(), ResumeDeployment].type Input should be 'resume-deployment' [type=literal_error, input_value='send-email-notification', input_type=str] For further information visit https://errors.pydantic.dev/2.10/v/literal_error actions.0.ResumeFlowRun.type Input should be 'resume-flow-run' [type=literal_error, input_value='send-email-notification', input_type=str] For further information visit https://errors.pydantic.dev/2.10/v/literal_error actions.0.CancelFlowRun.type...." When I look at it via the API explorer, it seems to be fine. Is this part of the CLI broken, or is there something wrong with my Automation? I just created it today (Prefect Cloud), and updated to the newest version of Prefect locally for the CLI.
m
thought for 134.8 seconds
Yes — this looks like a client/CLI schema mismatch, not a problem with your automation definition. What’s happening Your Cloud automation contains an action with type
send-email-notification
, but the current OSS/CLI automation schema only recognizes actions like
send-notification
,
run-deployment
,
call-webhook
, etc. When
prefect automation ls
fetches the automation from Cloud, the local client tries to deserialize it into its known
Automation
model and fails on that unknown action type. That matches the error exactly:
Copy code
Input should be 'do-nothing'
...
input_value='send-email-notification'
So in practice: - Your automation in Prefect Cloud is likely fine -
prefect automation ls
/
inspect
is what's broken for this automation type
- This is a bug or incompatibility in the local client/CLI schema Why this is confusing In Prefect 3.x, the documented/general-purpose notification action is
send-notification
, typically backed by a notification block. But Cloud appears to be returning a more specific action type,
send-email-notification
, that the Python client/CLI does not currently accept. CLI command verified
prefect automation
does have the expected subcommands: -
ls
-
inspect
-
create
-
update
- etc. So this is not a bad command; it’s the response validation that’s failing. What you can do right now 1. Use the Cloud UI or API explorer for this particular automation - Since you said the API explorer shows it correctly, that’s the most reliable path for inspection right now. 2. For programmatic creation, prefer
send-notification
if possible
- If your goal is “email these people when tagged flow/deployment failures happen”, the more portable/programmatic route is likely: - trigger on failure events - filter by the resource tags you care about - use a
send-notification
action tied to an email-capable notification block 3. Avoid relying on
prefect automation ls
for automations that use Cloud email actions
- At least until this mismatch is fixed. About tag combinations Yes, automations can target event/resource data, but the exact filter shape for “specific combination of tags on deployments/flows” is something I’d want to verify carefully before giving you code. If you want, I can help with either of these next steps: 1. Build a working automation definition in Python/YAML for: - flow/deployment failure events - matching a required set of tags - sending email notifications 2. Check whether this exact CLI bug is already tracked in GitHub issues/discussions Relevant docs: - Automations concepts - Create automations - Custom notifications If you want, I can draft the exact automation payload/code for your tag-based failure alerting next.
m
@Marvin related to this, when creating automations programatically, is it possible to create the send-email-notification records without specifying a block ID? Some code examples that I see (could be AI hallucinations) include a block ID. I don't see any blocks in my cloud UI for my created automations, so I assume they must be "under the hood"?
m
thought for 141.8 seconds
Short answer: if you're using the public Python models/API,
send-notification
requires a
block_document_id
.
So for programmatic creation, I would not assume you can omit it. What’s verified in Prefect 3.x The public action model is
SendNotification
, and it includes a required
block_document_id
field described as “The identifier of the notification block to use”. In other words, the supported SDK shape is effectively:
Copy code
python
from prefect.events.actions import SendNotification

SendNotification(
    block_document_id=...,
    subject="...",
    body="...",
)
There is not a public
SendEmailNotification
class in the OSS/client package. What this implies - If you create automations programmatically via the Python client/models, you should expect to provide a block document ID. - The Cloud UI may be using an internal or Cloud-specific representation for its built-in email action. - That internal representation is not currently reflected cleanly in the CLI/client schemas — which is consistent with the validation error you hit earlier. So your intuition is reasonable: the Cloud-created email automation may be backed by something “under the hood” that is not exposed as a normal user-visible block in the same way the SDK expects. Important nuance I can verify: - the public SDK action is
send-notification
- it requires
block_document_id
- the CLI currently chokes on Cloud automations returning
send-email-notification
I cannot confidently verify from the public OSS code exactly how Prefect Cloud stores those UI-created email automations internally. So I don’t want to overstate that part. Practical recommendation If your goal is reliable programmatic creation, use the supported/public route: 1. Create or reuse a notification block 2. Get its
block_document_id
3. Create the automation with
send-notification
That’s the safest path if you want something that works from code and aligns with the SDK. If you want to go that route, I can help you with code for: - creating an email notification block - finding its block document ID - creating an automation filtered to failed flow/deployment events with specific tags Relevant docs: - Automations concepts - Create automations - Custom notifications If you want, I can draft the exact end-to-end Python example next.
m
@Marvin What about creating it via YAML. Can we do that without needing to create a block first? Our goal is to have one code artifact that we can version control, without depending on anything being pre-created in the environment. Ideally this will allow us to test locally (local dockerized prefect server on each dev's machine), in our cloud test environment, and then our cloud prod environment.
m
thought for 127.3 seconds
Short answer: no — not with the supported YAML schema today. If you create an automation from YAML using
prefect automation create
, a notification action still needs a
block_document_id
. There is no supported inline email config like:
Copy code
yaml
actions:
  - type: send-notification
    smtp_server: ...
    recipients: ...
and there’s no “create this notification block as part of the automation YAML” feature either. So for your goal of a single version-controlled artifact: Prefect does not currently support a completely self-contained automation YAML for email notifications. You’ll need one of these patterns: Option 1: Two-step, fully codified setup - Step A: create/update the notification block from code - Step B: create/update the automation from code or YAML, referencing that block This still gives you everything in version control, just not as a single raw automation YAML file. Best practical pattern Keep: - a script that creates the notification block with a stable name in each environment - an automation template that refers to that block indirectly - a deployment script that resolves the block name to
block_document_id
For example: 1.
create_notification_block.py
2.
automation.template.yaml
3.
deploy_automation.py
That gives you reproducibility across: - local Prefect server - Cloud test - Cloud prod without requiring manual pre-creation in the UI. Important caveat for local dev If you want this to work on each developer’s local Dockerized Prefect server too, that environment still needs: - whatever email provider credentials you use - a block created in that local server instance So “no manual pre-created dependency” is achievable, but “no dependency at all” is not — the dependency just becomes codified bootstrap/setup instead of a manual UI step. Recommended approach for portability I’d suggest treating notification blocks like infrastructure/config resources: - Create them from code in each environment - Give them a consistent logical name, like
failure-alert-email
- Resolve the ID at deploy time - Then apply the automation That’s the cleanest way to keep things versioned and environment-portable. Why IDs are awkward
block_document_id
is environment-specific, so hardcoding it in YAML is usually a bad fit for: - local - test - prod That’s why a small wrapper script is usually better than pure static YAML. What I would recommend in your case Use Python as the source of truth instead of pure YAML, because then you can: - create or update the notification block - look up its ID - create or update the automation all in one version-controlled artifact. That gives you the “single artifact” behavior you want, even if under the hood it’s performing two API operations. Alternative if you want to avoid notification blocks entirely You could consider a
call-webhook
automation instead of email notification blocks, and point it at your own small notification service. That can sometimes be easier to make portable across environments, but it adds external infrastructure. Docs: - Automations concepts - Create automations - Custom notifications If you want, I can draft a single Python deployment script that: - creates/updates an email notification block - creates/updates the automation - supports local/test/prod via environment variables That’s probably the closest match to your desired workflow.
m
@Marvin the email notification blocks that are mentioned in the docs look like they're set up to use an internal SMTP server and credentials. That's not what I'm looking for. I'm looking for a way to reproduce the experience from the UI, where I go to Automations, create automation, click "email notification", and then fill in the emails, subject, and body. We then rely on Prefect Cloud's email server to send these notifications out. is there no way to replicate that experience from the CLI/SDK/API?
m
thought for 133.2 seconds
Short answer: as far as the public CLI/SDK/API goes, I don’t see a supported way to do that today. Specifically: - The Cloud UI can create an automation action that comes back as
send-email-notification
- The public Python/CLI automation models only support
send-notification
-
send-notification
requires a
block_document_id
- That’s why
prefect automation ls
is failing for you: the public client cannot deserialize the Cloud UI’s email action type So for the exact UX you described — “use Prefect Cloud’s own email sender, just provide recipients/subject/body, no block” — I can’t find a supported public interface that exposes it. What I can say confidently 1. The UI supports something the public client does not fully support - Your earlier validation error is strong evidence of this. - We also found a related discussion: GitHub discussion #19076 2. The public automation action exposed in the SDK is block-based - That means it expects
block_document_id
3. I cannot verify a documented public REST payload for
send-email-notification
- So I would not recommend building against an undocumented/private Cloud API shape unless you’re comfortable with it breaking. Practical conclusion If your requirement is specifically: - version-controlled - reproducible - works via CLI/SDK/API - uses Prefect Cloud-managed email delivery - does not require creating notification blocks first then I don’t see a supported way to achieve that today. Your current options appear to be: - Use the Cloud UI for that built-in email action, or - Use the public automation APIs with
send-notification
+ a notification block Unfortunately, those are not equivalent from an infrastructure/setup perspective. About the docs confusion Yes — the docs around notification blocks are describing the publicly supported automation/programmatic path, which is block-based. That is different from the more streamlined Cloud UI email experience. My recommendation If this feature matters for your workflow, the cleanest thing to do is treat it as a current product gap: - UI supports Cloud-managed email creation - public CLI/SDK/API does not appear to expose the same capability I can help with one of two next steps: 1. Draft the closest supported code-first workaround - likely notification blocks + automation creation script 2. Summarize this gap cleanly for community visibility - since this seems useful to other users too Relevant thread: - `prefect automation ls` fails with `send-email-notification` discussion If you want, I can also help you inspect the raw Cloud API payload in a safer way and tell you whether there’s an undocumented request shape that matches the UI — but I’d label that unsupported/private rather than recommended.