The 28 Slack Messages
Imagine you've built an ML platform. Product managers can deploy pre-built model templates to customers — select a template, pick a customer, click deploy. Easy.
One Tuesday afternoon, a PM deploys a click-through rate model to a new customer. The customer onboarded three days ago. The model template needs at least 14 days of interaction data to train.
The PM doesn't know this. Why would they? They're a product manager, not a data scientist. They click "Deploy," get a spinner for 90 seconds, and then:
Error: Training pipeline failed. Exit code 1.
That's it. No explanation. No guidance. No next step.
So the PM does what anyone would do — they message the engineering channel on Slack: "Hey, I tried to deploy CTR model to Customer Y and it failed. Can someone look?"
An engineer investigates. Twenty minutes later: "Oh, they only have 3 days of data. The model needs 14 days minimum. You'll have to wait until around March 5."
Now multiply this by every PM, every customer, every model type with different requirements. You get 28 Slack messages a week, each one asking some variation of "why did this fail?" And each answer is something the system already knew — it just didn't bother to tell anyone.
The system had all the information. It chose to say nothing useful.
The Pattern: Guide, Don't Block
Most systems handle bad input the same way: reject it.
User tries something invalid → "Error: Invalid request" → User confused
This technically works. The system is "safe." But the user is stuck, frustrated, and about to file a support ticket — which means a human ends up solving what the system should have.
Guard rails take a different approach:
User tries something → Validation fails → "Here's WHY, here's WHAT to fix, here's WHEN to retry"
The system still prevents the bad thing from happening. But instead of slamming a door in your face, it puts up a guardrail on the highway — you can see the edge, you know you're drifting, and you correct before going off the cliff.
The Failure Mode This Prevents
Guard rails solve a specific problem: self-serve systems that generate support tickets instead of successful outcomes.
Imagine you're building a platform where non-technical users trigger complex operations. Maybe it's:
- A product manager deploying an ML model to a customer
- A marketing team scheduling a push notification campaign
- An ops engineer provisioning infrastructure for a new region
These users don't have the mental model of the system. They don't know the prerequisites. They don't know what "Error: insufficient data for training pipeline" means.
Without guard rails, every failed operation becomes:
User → tries action → cryptic error → Slack message to engineering →
engineer investigates → "oh, you need 14 days of data first" →
user waits → tries again → maybe fails again
With guard rails:
User → tries action → "This customer has 3 days of data.
This model needs at least 14 days. Earliest deploy: March 5.
[Notify me when ready]"
No Slack message. No engineering ticket. No frustration. The system explained the constraint and offered a next step.
What Good Guard Rails Look Like
Back to the ML platform. Here's what that PM should have seen instead of "Exit code 1":
The Validation Checklist
Before the system accepts a deploy request, it runs a series of checks:
Notice what this does:
- Shows what passed — the user knows they're not doing everything wrong
- Explains what failed — specific, not generic
- Gives a date — "when" is more useful than "no"
- Offers a next action — "Notify me" means they don't have to keep checking manually
The Thresholds Are Part of the Template
Different models need different things. A simple bandit model might work with 7 days of data. A gradient-boosted model might need 30 days. A deep learning model might need 90 days and a GPU.
The guard rail thresholds aren't hardcoded — they're defined by the people who know: the data scientists who built the template. When DS publishes a template, they specify:
| Check | Bandit | LightGBM | Deep Learning |
|---|---|---|---|
| Min data days | 14 | 30 | 90 |
| Min interaction rows | 1,000 | 50,000 | 500,000 |
| Feature table required | No | Yes | Yes |
| GPU required | No | No | Yes |
The platform enforces these automatically. DS defines the rules once, every deployment is validated against them forever.
The Anatomy of a Good Guard Rail
1. Validate Early, Not Late
Don't let the user fill out a 10-step form, click "Submit," and THEN tell them step 2 was wrong. Validate as early as possible.
Even better — validate before they even start. If you know a customer doesn't have enough data, show a warning on the template selection page. Don't wait until they've configured everything.
2. Be Specific, Not Generic
❌ "Validation error"
❌ "Cannot deploy model"
❌ "Insufficient data"
✅ "Customer Y has 3 days of interaction data. CTR Bandit requires at least 14 days."
Every word in the error message should reduce the user's uncertainty. If they read it and still don't know what to do, the message failed.
3. Tell Them When, Not Just No
❌ "Not enough data. Try again later."
✅ "Not enough data. Earliest deploy date: March 5, 2026."
"Later" is useless. A date is actionable. They can set a calendar reminder and come back.
4. Offer a Next Step
The best guard rails don't just inform — they offer an action:
- "Notify me when ready" (subscribe to a check)
- "Deploy with reduced accuracy" (accept the risk explicitly)
- "Contact DS team" (escalate with context pre-filled)
The user should never be left staring at a message with nothing to click.
Where You've Seen This Pattern
Once you recognize guard rails, you see them everywhere:
- Stripe's onboarding doesn't say "Error 403: Account not verified." It shows a checklist of what's complete and what's missing, with time estimates and action buttons for each step.
-
GitHub branch protection doesn't just reject your push to
main. It shows which checks failed (with links to logs), which reviews are missing (with names), and a "Re-run" button for flaky tests. - Terraform plan shows you exactly what will be created, changed, and destroyed before you apply — so you make the call with full information, not after the damage is done.
- Google's "Did you mean?" — the original guard rail. You search for "pythn tutoral" and instead of "no results," you get a suggested correction and results anyway.
These are all systems that chose to guide instead of block. The user is still prevented from doing the wrong thing — but they're never left staring at a wall.
When You Need Guard Rails
Two conditions:
Non-expert users trigger complex operations. If only senior engineers use the system, a terse error might be fine. If product managers, marketers, or ops people use it — they need guidance.
Failures are recoverable but wasteful. If the system would eventually fail anyway (out of memory, bad training data, missing features), it's better to catch it before spending 2 hours and $50 in compute on a doomed training run.
The guard rails pattern works best at system boundaries — where user intent meets system constraints. That's where the mismatch between "what I want to do" and "what the system can handle" is highest.

Top comments (0)