Skip to content

Improve the default SMTP task failure email template - #67931

Draft
wilmerdooley wants to merge 1 commit into
apache:mainfrom
wilmerdooley:oss/issue-61667
Draft

wilmerdooley wants to merge 1 commit into
apache:mainfrom
wilmerdooley:oss/issue-61667

Conversation

@wilmerdooley

@wilmerdooley wilmerdooley commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor

Resolves #61667.

The default email that SmtpNotifier sends on task failure does not show which DAG or task failed, so it is hard to triage at a glance. This restyles the default templates for readability, keeping the change minimal and backward compatible.

What changed

  • templates/email.html: add DAG and Task rows (previously missing) alongside the existing Run ID, Try, State, Host and log link, and lay the body out as a scannable table. Layout uses a plain <table> with inline cell styles only (no <style> or <head> styling, no CSS grid or flexbox), so it renders consistently in Gmail and Outlook.
  • templates/email_subject.jinja2: a more scannable subject, [Airflow] {{ ti.dag_id }}.{{ ti.task_id }} {{ ti.state }} - Run {{ ti.run_id }}. The SLA branch is unchanged.
  • tests/unit/smtp/notifications/test_smtp.py: update the one assertion that pins the default subject.

Scope and compatibility

  • Only the SMTP provider default templates are touched. airflow-core and task-sdk are left alone, since email integration is moving out of core (PR [WIP] Migrate core EmailOperator to SMTP provider #30531).
  • Backward compatible: a user-provided subject_template or html_content_template (connection extras) still takes precedence over the bundled defaults.
Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude Code


Important

🛠️ Maintainer triage note for @wilmerdooley · by @potiuk · 2026-07-28 16:10 UTC

Helpful heads-up from the maintainers — please address before this PR can be reviewed:

  • ❌ Unit tests. See docs.

The ball is in your court — you've been assigned to this PR. Fix the above, then mark it Ready for review.

See the Pull Request quality criteria for how to fix each item. There is no rush.

Note: your branch is 1310 commits behind main — please rebase and push again to get up-to-date CI results.

Automated triage — may be imperfect; a maintainer takes the next look. We use this two-stage triage process so maintainers' limited time goes to the conversation with you.

Signed-off-by: wilmerdooley <wilmerdooley1@gmail.com>
@wilmerdooley wilmerdooley changed the title Improve default task failure email template for readability and operatio Improve the default SMTP task failure email template Jun 3, 2026
@eladkal

eladkal commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Can you please add before and after images if the template?

@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jun 3, 2026
@wilmerdooley

wilmerdooley commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Before/after renders of the default task-failure email, with the same sample failure context in both:

Before (main):
before

After (this PR): adds DAG and Task rows and lays the fields out as a card with a header and a View Logs button.
after

@wilmerdooley

Copy link
Copy Markdown
Contributor Author

I looked into the two red checks and they aren't coming from this change. Both failed during the runner setup step ("Cleanup repo"), before the code was even checked out, when the runner tried to pull the bash:latest image and the Docker Hub pull timed out (exit 125). Because that setup step failed, the checkout and all the actual test steps were skipped rather than run, so the tests never executed in those two jobs. Everything else is green, including the smtp unit tests in the other matrix jobs.

A re-run of just those two jobs should clear them, but I can't trigger that myself as an external contributor. How would you prefer to proceed? Happy to rebase onto current main and push if a fresh commit is the easier way to re-trigger CI, though that's your call.

@potiuk potiuk removed the ready for maintainer review Set after triaging when all criteria pass. label Jul 8, 2026
@Vamsi-klu

This comment was marked as spam.

@potiuk
potiuk marked this pull request as draft July 28, 2026 16:10
rjgoyln added a commit to rjgoyln/airflow that referenced this pull request Sep 17, 2026
Adapted from apache#67931 by Wilmer Dooley, whose PR went stale. The bundled body
never named the Dag or the task, and the state field rendered the Python enum
repr rather than the state itself. The heading is derived from the state so
the template still reads correctly on the success and retry callbacks that
share it.
rjgoyln added a commit to rjgoyln/airflow that referenced this pull request Sep 17, 2026
Adapted from apache#67931 by Wilmer Dooley, whose PR went stale. The bundled body
never named the Dag or the task, and the state field rendered the Python enum
repr rather than the state itself. The heading is derived from the state so
the template still reads correctly on the success and retry callbacks that
share it.
rjgoyln added a commit to rjgoyln/airflow that referenced this pull request Sep 17, 2026
Adapted from apache#67931 by Wilmer Dooley, whose PR went stale. The bundled body
never named the Dag or the task, and the state field rendered the Python enum
repr rather than the state itself. The heading is derived from the state so
the template still reads correctly on the success and retry callbacks that
share it.
rjgoyln added a commit to rjgoyln/airflow that referenced this pull request Sep 27, 2026
Adapted from apache#67931 by Wilmer Dooley, whose PR went stale. The bundled body
never named the Dag or the task, and the state field rendered the Python enum
repr rather than the state itself. The heading is derived from the state so
the template still reads correctly on the success and retry callbacks that
share it.
rjgoyln added a commit to rjgoyln/airflow that referenced this pull request Sep 27, 2026
The subject rendered {{ ti }}, which on Airflow 2 gave the TaskInstance repr
and now dumps every field of a Pydantic model -- UUIDs, the task object and
the bundle instance included -- while neither body named the Dag or the task.
The notifier's own template rendered the state enum's Python name, and both
offered a "Mark success" link that only reaches the log, since Airflow 3 has
no mark-success endpoint to link to.

Template work adapted from apache#67931.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve default task failure email template for readability and operational clarity

4 participants