My Trading Bot's Silent Killer: How Forgetting to Load `.env` Across Scripts Silenced Discord Notifications

2026年8月5日1 次浏览来源:Dev.to阅读原文

Hey everyone, it's your friendly neighborhood dev-dad here.

Mid-thirties, full-time engineer by day, battling AI trading bots by night (weekends, really).

Today, I want to share a subtle but potentially catastrophic bug I found in my bot.

Seriously glad I caught this before deploying with real money.

The symptom: Discord notifications for order fills just weren't arriving.

The culprit: I forgot to load my variables consistently across multiple Python scripts.

This is a super common pitfall when you're linking several Python scripts in a personal project, and it can be a real headache.

What Happened: A "Silent Failure" Uncovered by a DRY_RUN Last weekend, I was running my usual DRY_RUN tests for my FX bot.

My bot's logic is split into two main parts: , which strategizes trades, and , which actually sends orders to the exchange.

The console logs looked perfectly normal. seemed to be doing its job: I saw messages like "[DRY_RUN] Order placed: ...".

But the Discord notifications, which should have been firing, never appeared.

At first, I thought it was a Discord outage or just a delay.

But after 30 minutes, nothing.

Something was definitely wrong.

Thinking about what would have happened if this were real money sent shivers down my spine. "I thought I placed an order, but it never went through." "I thought I closed a position, but I was still holding it." Bugs in notification systems are terrifying because they create these silent failures.

You think everything is okay, but it's not.

This is precisely how real money gets lost.

The Investigation: Unmasking the Culprit To narrow things down, I first tried calling (which handles all notifications) directly.

It worked flawlessly; the Discord notification came through.

This pointed to an issue within , which calls .

I re-examined 's logs more carefully and immediately saw it: the webhook URL being passed to the notification function was .

Ah, there it is.

But why ?

I have the webhook URL stored in my file, and it's loaded correctly when executes.

Comparing and 's code, the reason became painfully obvious. correctly includes at the top: However, , the problem child, was missing .

This meant that when I ran the full flow (where calls ), would load the variables first, so appeared to work.

But if I ran directly for testing, or if it was called from a different entry point, no one was loading .

Consequently, the webhook URL was never set, and notifications silently failed.

My code was relying on an "implicit assumption" about its execution context.

This is the kind of thing that would get flagged in a code review with a team, but in solo dev, it's easy to miss.

The Fix: Resolve Dependencies Where They're Used The fix was straightforward once the cause was clear.

I added to before any notification calls.

Before: In this scenario, would initialize, and would return , leading to a silent failure.

After: I used to ensure that no matter the current working directory, it will always locate the file in the project root.

Now, will always correctly load the webhook URL, regardless of how it's executed.

It's a fundamental principle, really: if your code depends on a certain feature (like environment variables), the code using that feature is responsible for resolving that dependency.

A simple truth, but easily overlooked.

Lessons Learned and Takeaways I took away three key lessons from this experience: DRY_RUN Tests are Gold The value of catching "normal-looking anomalies" like this, without any financial impact, is immense. "Seems to be working" is the most dangerous state.

Never skip DRY_RUNs before live deployment.

Eliminate "Implicit Assumptions" Between Scripts When splitting logic across files, it's easy to create implicit assumptions like "that other file must have initialized this." For project-wide settings like , explicitly loading them at each entry point, or at the top of any module that uses them, is a much more robust design.

Consider Assertions for Critical Operations While logs helped me catch this, for even greater robustness, adding an assertion right before critical operations like sending an order or a notification could be beneficial.

Something like would immediately flag misconfigurations.

Operating a personal bot means constantly battling these subtle bugs.

But each one you squash makes the system stronger.

Another weekend, another step towards a smarter bot.

分享
Baike.dev

baike.dev helps you discover great languages, frameworks, databases, DevOps and cloud-native tools.

Quick links

About

Contribute

Found a great developer tool? Share it with the community.

Submit a tool
© 2026 baike.dev Developer EncyclopediaUpdated daily · Discover great developer tools