Bad Requirements Cost More Than Bad Code
I once watched a team spend an entire sprint building a feature that the PM hadn't fully thought through. The edge cases weren't documented. The error states weren't considered. The mobile experience was an afterthought. When the PM saw the implementation, the response was "that's not what I meant." Three weeks of work, thrown away.
That experience — multiplied across thousands of teams — is why IBM found that fixing a requirement error after release costs 100x more than catching it during the requirements phase. Not because requirements documents are magic, but because clear thinking before building prevents expensive rework after.
The most common requirement failures I see:
- "Make it user-friendly" — What does that mean? Fast load times? Fewer clicks? Bigger buttons? This isn't a requirement; it's a wish.
- Missing error states — "The user submits the form." Great. What happens when the server is down? When they enter invalid data? When their session expires mid-submission?
- Unstated assumptions — "It works on mobile" (which nobody mentioned until the sprint review)
- Solution-masquerading-as-requirement — "Add a dropdown menu" instead of "Users need to select their country from 195 options"
Good requirements don't have to be long. They have to be clear, testable, and focused on outcomes.
User Stories: Small, Valuable, Testable
A user story captures a feature from the perspective of someone who'll actually use it. The template is intentionally simple:
As a [type of user], I want to [do something], so that [I get some benefit].
Real examples:
- "As a hiring manager, I want to filter candidates by experience level, so I can quickly find qualified applicants for senior roles."
- "As a returning student, I want to see my recently viewed courses on the homepage, so I don't have to search for them again."
- "As a finance admin, I want to export transaction history as CSV, so I can import it into our accounting software."
The "so that" clause is the most important part. It forces you to articulate the why. If you can't explain the benefit, the story probably isn't worth building.
Use the INVEST checklist to evaluate each story:
- Independent — Can be built and delivered without waiting for other stories
- Negotiable — The details are a conversation, not a dictation
- Valuable — Delivers clear value to a user or the business
- Estimable — The team can roughly estimate the effort
- Small — Completable in a single sprint
- Testable — You can write acceptance criteria that prove it works
Acceptance Criteria: The Contract Between PM and Engineering
Acceptance criteria turn a vague user story into something the team can actually build and test. They define the specific conditions that must be true for the story to be considered done.
Given-When-Then format (great for complex logic):
Given a logged-in user is viewing a course page
When they click the "Add to Wishlist" button
Then the course appears in their wishlist
And the button changes to "Remove from Wishlist"
And a toast notification confirms "Added to wishlist"
Given a logged-in user with 50 wishlisted courses (the maximum)
When they try to add another course
Then an error message displays "Wishlist is full. Remove a course to add new ones."
And the course is NOT addedChecklist format (better for straightforward features):
- Wishlist button visible on all course cards and course detail pages
- Clicking adds/removes the course (toggle behaviour)
- State persists across sessions (stored server-side)
- Maximum 50 courses per wishlist
- Accessible via keyboard (Enter and Space keys)
- Works on mobile (minimum 44x44px touch target)
The format matters less than the coverage. Whichever style you use, make sure you cover: the happy path, error states, edge cases, and any non-functional requirements (performance, accessibility).
PRDs: When User Stories Aren't Enough
User stories work well for individual features. But when you're building something complex — a new billing system, a multi-step onboarding flow, a marketplace feature — you need a more comprehensive document. That's the PRD.
Here's the template I use. Adapt it to your team's needs, but don't skip the sections marked as essential:
- Problem Statement (essential) — What problem are we solving? Who has it? How painful is it? Include data: support tickets, user research quotes, or churn analysis.
- Goals & Success Metrics (essential) — "Reduce checkout abandonment from 68% to 45% within 60 days of launch." Specific, measurable, time-bound.
- User Personas — Who are the primary and secondary users? What are their technical skill levels?
- User Flows (essential) — Step-by-step journey through the feature. Diagrams are worth a thousand words here.
- Functional Requirements (essential) — Detailed descriptions of each capability, with acceptance criteria
- Non-Functional Requirements — Performance targets, security considerations, accessibility standards
- Design — Link to Figma mockups or wireframes
- Technical Notes — API changes, data model impacts, third-party integrations. Written with engineering, not for engineering.
- Out of Scope (essential) — What we're explicitly NOT doing. This prevents scope creep better than any process.
- Open Questions — Decisions still pending. Be transparent about what you don't know yet.
The Edge Case Checklist Every PM Needs
The features you didn't spec are the ones that bite you. Here's a checklist I run through for every feature. Print it. Tape it to your monitor.
States to consider:
- Empty state — What does it look like with zero data? First-time users will see this.
- Loading state — What do users see while content loads? A spinner? A skeleton screen?
- Error state — Network failure, server error (500), validation error, timeout
- Partial state — What if data is incomplete? A user profile with no avatar? A course with no reviews?
- Maximum state — 1,000 items in a list. A name that's 200 characters. An image that's 20MB.
User scenarios to consider:
- New user (no history, no preferences, no data)
- Power user (thousands of items, complex workflows)
- User without permission (what do they see? What error do they get?)
- Two users editing the same resource simultaneously
- User on slow 3G mobile connection
- User with a screen reader or keyboard-only navigation
You don't need to solve all of these upfront. But you need to acknowledge them. Write "Out of scope for V1: concurrent editing" and your engineering team knows it's intentionally deferred, not accidentally forgotten.
Communicating Requirements Without Losing Your Mind
A perfectly written PRD that nobody reads is worthless. Communication is half the job.
Before development starts:
- Walk through the requirements with the full team — don't just drop a document link in Slack
- Start with the problem and the "why." Engineers who understand the purpose make better trade-off decisions independently.
- Use visual aids. A user flow diagram, a Figma prototype, or even a hand-drawn sketch communicates faster than paragraphs of text.
- Explicitly invite pushback. "What am I missing? What's going to be harder than I think?" Engineers often see technical constraints you haven't considered.
During development:
- Be available for questions. The faster you respond, the less time the team spends guessing or building the wrong thing.
- When questions reveal gaps in your spec, update the document. Don't let decisions live only in Slack threads.
- Review in-progress work early. A five-minute demo on day 3 catches misalignment before it becomes day-10 rework.
After launch:
- Measure against the success metrics you defined. Did you hit the targets?
- If you didn't — and this is critical — don't bury it. Write a brief retrospective: what did we learn? What would we do differently?
The PMs that engineering teams love working with aren't the ones who write the longest documents. They're the ones who think clearly, communicate concisely, and stay engaged throughout the build.
Ready to Take the Next Step?
Our tutorials are just the beginning. Explore our expert-led courses and certifications for hands-on, career-ready training.