Repository navigation
Conversation
A template send on send/email/ now tells cdp-api which version of the template's workflow holds the content Django graded the hash against, as send.hogFlowVersion. A cdp-api that knows the field sends from that version or a newer one instead of an older cached copy. One that does not ignores it, because the accepted send schema strips unknown keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The graded version must not come from a read replica, or an older copy could satisfy the floor. A workflow deleted between grading and the version read now logs a queue rejection, like the 404 from cdp-api, instead of an exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When cdp-api answers 503 workflow_version_behind, the caller gets the existing 503 delivery_unavailable, with detail, why and fix saying the template's newest version has not reached the pipeline yet. The sub-code stays in the log reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the code-first rebuild of the email send stack; new in the rebuild, with no closed PR to replace: a template send delivers the content Django graded (decision D3 on map #461).
Problem
send/email/right after an upload can deliver the previous content, while Django answered that the caller'stemplate.hashis current.Impact
Pays into Grow Workflows through billed
workflows_emailsactions per paying org: a developer who uploads a template and sends it at once gets the new content. In scope: thesend/email/route.Merge Danger
Note
🟢 Merge risk: low · two-way door: a revert stops sending the version, and delivery works as today
send/email/only, behindworkflows-email-from-code. Rendered-content sends and the legacy template send route don't change.Changes
send.hogFlowVersion. Django reads it after grading the hash, from the writer database, so it is never older than the graded content.Unavailableto the caller), without a stack trace in the log.503 delivery_unavailable, withwhyandfix:{ "type": "server_error", "code": "delivery_unavailable", "detail": "This template's newest version hasn't reached the email pipeline yet.", "attr": null, "why": "The email pipeline still holds an older version than the one PostHog checked the send against, so nothing was sent.", "fix": "Retry in a few seconds. If you sent an Idempotency-Key, use the same key.", "docs_url": ".../transactional-email-api#delivery_unavailable" }workflow_version_behind, which never reaches the caller.Unavailablegains optionaldetail,whyandfix, and only this case sets them.How did you test this code?
Test seams: the DRF client on
send/email/, asserting the body posted to cdp-api (test_transactional_email.py).Test rationale, each run red first:
senddict, which pins that the field is absent there.workflow_version_behindanywhere in the body. The existing 503 rows pin that their bodies have nowhyorfixkey at all, not even a null one.Proofs: live and cross-version runs are in #584, with this head as the Django side. Prod shape: a gap until read-only production access exists on 2026-11-02.
CI: the fork has no Depot runners, so those jobs never start, and no secret for the project-board app, so
flags-project-boardfails; the other GitHub-hosted checks pass. The lane check passes: against master the PR changes only the Python and frontend side.Release status
Docs update
None in this PR. The explained 503 links to the
#delivery_unavailableanchor of the transactional email API docs, which the docs for this stack need to carry.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)
srv2of map Map: send code-managed email templates with one PostHog call #461, for decision D3.tdd,writing-tests,writing-user-facing-copy,pr-description,writing-pr-descriptions.delivery_unavailablewith the version lag indetailandwhy; replaces a new publicworkflow_version_behindcodeInvolvement: one decision from Michael and one from the map's conductor; review round 1 (GPT-6.1 Sol, Opus fresh eyes) fixed, then final reads by GPT-6.1 Sol; live and cross-version proof captured in #584.
🤖 Generated with Claude Code