5 days ago
Ran the same diagnostic through Railway's dashboard AI Agent. Independent analysis
returned identical conclusion: "The issue is at the container runtime injection
layer. Something is systematically excluding these 4 specific variable names from
the environment passed to your container, even though they exist in Railway's
control plane and are accessible via railway run."
Agent's hypothesized causes (matches my analysis):
1. Managed variable binding via Stripe integration plugin path
2. Variable name filtering at injection layer
3. Scope shadowing (plugin/integration scope overriding Service scope)
4. Sealed secret state preventing standard injection
RESOURCE IDS (from Railway Agent):
- Service ID: 25554b45-af72-43b0-bf83-269fc1dd774f
- Project ID: 75065304-e592-4474-85af-59aa6e7784f5
- Environment ID: 7e962f87-dbf4-4784-8a26-9c8b8af1bb3c
- Latest deployment ID: 407f1516-2614-44fb-847f-cf1f89e29ae2
- Affected variable names: STRIPE_WEBHOOK_SECRET_FOUNDER,
STRIPE_PERSONA_PLUS_WEBHOOK_SECRET, STRIPE_PERSONA_WEBHOOK_SECRET,
STRIPE_VOICE_TOPUP_WEBHOOK_SECRET
Bonus finding from Agent diagnostics: stale function body drift on triggers
enforce_battle_war_tax and enforce_spin_war_tax (md5 mismatch between expected
and actual). Separate from Layer 1 issue but worth flagging for engineering
review while they're in there.
2 Replies
Status changed to Open Railway • 5 days ago
5 days ago
"Update 2026-05-08 20:10 UTC: Added a 5th webhook signing secret today (STRIPE_B2B_LICENSE_WEBHOOK_SECRET, sha256_first4=78c0, len=38, whsec_ prefix), invisible to deployed container's process.env. Now 5 of 7 webhook secrets affected; 2 (the older STRIPE_WEBHOOK_SECRET for seat and STRIPE_TOKEN_PACK_WEBHOOK_SECRET) still propagate correctly. The propagation gap reproduces on freshly-created webhook secrets, not just May-7-rotated ones — narrows the failure class. Architect tested via Raw Editor save + manual deploy with rolled-back builder + fresh container (uptime 42s post-build). Same result."
2 days ago
The strongest way to narrow this is to prove whether the missing vars disappear only inside the deployed app process, or anywhere inside the deployed container.
I would add one temporary diagnostic endpoint or startup log that prints only metadata, never secret values:
- variable name
- present: yes/no
- length
- prefix check only, e.g. startsWith("whsec_")
- sha256 first 4 chars if you need identity matching
Then compare four surfaces for the same deployment ID:
- Railway UI variable list
- railway run env output filtered to STRIPE_ names
- build log / build-time env, if your Dockerfile or build step reads env
- runtime container process via the temporary endpoint/log
If the Railway UI and railway run have the variables, but the deployed runtime does not, that is not a Stripe/webhook issue and not app code reading the wrong name. It is specifically runtime env materialization for that service/environment/deployment. If build-time has them but runtime does not, mention that too because it points away from variable storage and toward runtime injection.
Two extra things worth checking before Railway engineering picks it up:
- Confirm the affected names are not referenced as service variables from another service/environment scope. A stale reference can look present in the UI but resolve empty at runtime.
- Create one neutral test variable with the same length/prefix shape but a non-Stripe name, e.g. TEST_WEBHOOK_SECRET_RUNTIME_CHECK. If that injects and the STRIPE_*WEBHOOK_SECRET* names do not, Railway has a name-pattern/integration collision. If it also fails, the bug is broader sealed-secret/runtime injection state.
The useful escalation packet is: deployment ID, the exact affected variable names, metadata-only output from railway run, metadata-only output from the deployed runtime, and whether a neutral control variable injects. Do not share the actual whsec_ values publicly.