AI can build a working application faster than ever.
Give an AI coding agent a prompt, and it might generate a frontend, connect an API, create database models, write authentication logic, and even add tests.
A few years ago, building all of that could take days. Now, you can get a first version in minutes.
That's incredible.
But there's one question we should ask before celebrating:
Would you trust the code it generated with real users, real money, and real production data?
Because there's a big difference between code that works in a demo and software that's ready for production.
And I think that's one of the most important things developers need to understand about AI-assisted development.
1. Working Code Doesn't Always Mean Correct Code
Imagine you're building a simple application where users can manage their personal projects.
You ask an AI coding agent to create an API endpoint that returns a project by its ID.
It generates something like this:
app.get("/projects/:id", async (req, res) => {
const project = await db.project.findUnique({
where: {
id: req.params.id
}
});
res.json(project);
});
Looks reasonable, right?
The endpoint retrieves a project and returns it as JSON.
But there's a problem.
What happens if one user requests another user's project?
If the application doesn't verify ownership or access permissions, a user might be able to access data they shouldn't see.
The code works exactly as written. The problem is that it doesn't enforce the application's security requirements.
A safer implementation would check authorization before returning the project:
app.get("/projects/:id", async (req, res) => {
const project = await db.project.findFirst({
where: {
id: req.params.id,
ownerId: req.user.id
}
});
if (!project) {
return res.status(404).json({
error: "Project not found"
});
}
res.json(project);
});
This example assumes authentication middleware has already verified the user and populated req.user. A real application also needs appropriate validation, error handling, and database-specific considerations.
The lesson isn't that AI always writes insecure code.
The lesson is that a successful response doesn't prove that an endpoint is secure or correct.
Someone still needs to understand what the code should protect.
2. AI Can Pass Tests and Still Miss Important Problems
Tests are essential, but they only tell us what we've actually tested.
Imagine an AI agent generates a payment feature.
You test it with these scenarios:
- A customer makes a successful payment.
- An invalid payment is rejected.
- The payment amount appears correctly.
- The confirmation message is displayed.
Everything passes.
Does that mean the payment system is ready for production?
Not necessarily.
What happens if the payment provider confirms a payment but your database update fails?
What if the payment provider sends the same webhook twice?
What if a customer retries a request because the first response was delayed?
What if someone changes the price in a request before submitting it?
These scenarios require more than checking whether the happy path works.
You need to consider failures, retries, concurrency, and trust boundaries.
For example, payment systems often need idempotency: processing the same payment operation or webhook more than once should not accidentally charge a customer twice or duplicate an order.
They also need server-side price validation and reliable reconciliation with the payment provider.
An AI agent can help implement these safeguards. But developers must verify that the safeguards exist and behave correctly.
Passing tests means the tested scenarios passed. It doesn't mean every important scenario has been covered.
3. The Most Dangerous Bugs Aren't Always Obvious
Some bugs are easy to notice.
A button doesn't work. A page crashes. An API returns an error.
Other problems remain hidden until real users start using the application.
Here are five examples worth checking in AI-generated code:
Security and authorization
Does every protected operation verify that the current user has permission to perform it?
Authentication tells you who the user is. Authorization determines what that user can do.
Database integrity
Can concurrent requests create duplicate records? Can deleting one record leave related data inconsistent? Are important constraints enforced by the database?
Error handling
What happens when an external API times out, a database connection fails, or an unexpected value appears?
Performance
Does an endpoint load thousands of records when it only needs ten? Does a page make unnecessary API requests? Can a database query become expensive as the application grows?
Configuration and secrets
Are API keys exposed in frontend code? Are production secrets stored safely? Does the application fail securely when required environment variables are missing?
None of these problems is unique to AI-generated code. Experienced developers make mistakes, too.
But when AI generates large amounts of code quickly, it's easy to produce more code than you can carefully review.
That's where the real risk begins.
4. Stop Asking Only "Does It Work?"
When an AI coding agent finishes a feature, it's tempting to run the application, click a few buttons, and move on.
Instead, try asking a different set of questions.
Ask the AI to challenge its own implementation
After the initial implementation, use a separate review step:
Review this implementation as a critical software engineer.
Do not assume the code is correct just because it works.
Check for:
1. Authentication and authorization problems.
2. Data leaks between different users.
3. Input validation issues.
4. Database consistency and race conditions.
5. Missing error handling.
6. Security vulnerabilities.
7. Performance problems.
8. Missing tests and edge cases.
For every finding:
- Explain the actual risk.
- Identify the affected code.
- Describe how the problem could be reproduced.
- Suggest a concrete fix.
Do not claim an issue exists unless you can support it
with evidence from the code or a reproducible test.
This is a useful starting point, but it isn't a security guarantee.
An AI reviewer can miss vulnerabilities or report problems that aren't real. For important systems, combine code review with automated security tools, targeted tests, and independent verification.
Also, don't ask only for a list of problems. Ask for evidence.
A useful review should explain what can go wrong, why it matters, and how you can verify the finding.
5. Give AI a Smaller Job, Then Verify the Result
There's another habit that can make AI-assisted development more reliable: stop treating a large feature as one giant prompt.
Suppose you want to build a complete subscription system.
Instead of asking an AI agent to build everything at once, divide the work into smaller stages.
Step 1: Define the requirements
Specify subscription states, payment flows, cancellation rules, access permissions, and failure scenarios.
Step 2: Design the implementation
Review the database structure, API contracts, and important security decisions before generating all the code.
Step 3: Implement one part at a time
Build the subscription model, payment integration, webhook handling, and access-control logic in manageable pieces.
Step 4: Test each part
Check normal behavior, invalid inputs, repeated requests, failed operations, and unexpected states.
Step 5: Review the integration
Make sure the individual components work correctly together.
Step 6: Verify the deployment
Check production configuration, database migrations, logging, monitoring, and rollback procedures.
This approach doesn't eliminate bugs.
What it does is make problems easier to isolate, understand, and fix.
You can still move quickly with AI. You just avoid making speed your only measure of progress.
6. The Developer's Job Is Changing, Not Disappearing
I don't think the most important question is whether AI can write code.
It clearly can.
The more interesting question is what developers should focus on when writing code becomes faster and easier.
In my view, the answer is engineering judgment.
A developer needs to understand the requirements, choose an appropriate design, identify risks, verify the implementation, and take responsibility for the result.
AI can help with all of these tasks.
It can explain unfamiliar code, suggest alternative architectures, generate tests, identify potential vulnerabilities, and automate repetitive work.
But generating a suggestion and proving that the suggestion is correct are two different things.
As AI tools become more capable, understanding the fundamentals becomes even more valuable.
You need to recognize when an implementation makes sense, when an assumption is dangerous, and when more evidence is required.
You don't need to reject AI to become a better engineer.
You need to learn how to use it without surrendering your judgment.
7. My Practical Checklist Before Shipping AI-Generated Code
Before deploying a feature built with AI assistance, I'd want answers to these questions:
- [ ] Does the implementation satisfy the actual requirements?
- [ ] Are authentication and authorization enforced on the server?
- [ ] Can one user access another user's private data?
- [ ] Are inputs validated on the server?
- [ ] Are errors handled without exposing sensitive information?
- [ ] Have important edge cases been tested?
- [ ] Can retries or concurrent requests cause duplicate or inconsistent operations?
- [ ] Are secrets kept out of public code and logs?
- [ ] Have database queries and API calls been reviewed for performance?
- [ ] Have automated checks and relevant security tools been run?
- [ ] Can the feature be monitored and rolled back if something goes wrong?
Not every feature needs the same level of scrutiny.
A personal prototype and a production payment system have very different risk profiles.
The higher the potential impact of a failure, the more evidence and independent verification you should require.
The goal isn't to review every line manually forever.
The goal is to build a development process that catches important problems before users experience them.
Final Thoughts
AI coding agents have changed how quickly we can build software.
That's a good thing.
Developers can experiment faster, automate repetitive tasks, and spend more time solving meaningful problems.
But faster code generation doesn't automatically produce more reliable software.
A working demo is not proof of security. Passing tests is not proof of completeness. And an AI agent saying "implementation complete" is not evidence that a feature is ready for production.
The real skill is knowing how to turn generated code into software you can confidently maintain.
Don't just ask AI to build your application. Ask it to help you prove that your application works correctly. Then verify the evidence yourself.
Because when real users depend on your software, the quality of the result matters more than the speed at which the code was generated.
Let's discuss
What's the most important thing you check before shipping code generated by an AI coding agent?
Do you focus on tests, security reviews, manual code review, production monitoring, or something else?
I'd love to hear what other developers are doing to make AI-assisted development more reliable.
Top comments (2)
"Passing tests means the tested scenarios passed" is the line every team shipping AI code should pin somewhere visible. The /projects/:id example is spot on: IDOR bugs are the ones AI writes most confidently, because the happy path looks perfect.
My #1 check before shipping: I write the abuse tests myself (user A requests user B's data, same webhook fired twice, price tampered in the request) before letting the agent touch the implementation. If the agent writes both the code and the tests, they tend to share the same blind spots.
The "don't claim an issue unless you can support it with evidence" line in your review prompt is a great touch too. It cuts a lot of noise. Bookmarking the checklist.
I'm not directly involved in development now, but before joining my current project I built things using only AI. My coding knowledge is just the basics I picked up a little in school. You described what I felt back then, and how to fix it, really well. When I was vibe coding, I was so focused on solving the feature in front of me and moving on to the next one that I leaned on the AI and ignored bugs. This is something I'll keep in mind for my own personal projects. Thanks for the good advice.