I Don’t Know What I Don’t Know
I do free consultations. Thirty minutes, one-on-one, talking through whatever someone is building with AI or thinking about building. I do several of these every week. They are consistently the most useful conversations I have, because I get to see exactly where people are and what they are struggling with.
And here is the pattern: about nine out of ten times, within the first few minutes, the person says some version of the same thing.
“I don’t know what I don’t know.”
They say it like a confession. Like it is the thing they are most embarrassed about. Like admitting it means they are not cut out for this.
I want to tell you something about that phrase, because if you have ever thought it or said it, you need to hear this: it is the single most accurate and useful thing a vibe coder can say. Not because it describes a problem, but because it describes the beginning of solving one.
Why Vibe Coding Creates This Feeling
There are other skills where you learn by doing and gradually discover what you do not know. Cooking. Photography. Running a business. You try something, it does not turn out great, and the gap between what you wanted and what you got teaches you what to learn next. The feedback is visible. You can taste that the sauce is off. You can see that the photo is blurry. The gap between “what I know” and “what I need to know” reveals itself naturally.
Vibe coding does not work like that.
When you describe an app to an AI tool and it builds something that works, the result looks complete. It runs. It does what you asked for. The interface looks polished. You click around to test it and everything functions. There is no obvious gap between what you wanted and what you got.
But underneath that working surface, dozens of decisions were made that you never saw. The AI chose how to store your data. It decided who can access what. It picked an approach for handling errors (or, more often, it did not handle errors at all). It made choices about how components connect, which libraries to use, how authentication works, and what happens when something fails.
These are not minor details. They are the kinds of decisions that determine whether an app survives contact with real users, whether it stays secure, whether you can add features six months from now, and whether a small bug can cascade into a serious problem. In traditional software development, these decisions are made deliberately by people who understand the tradeoffs. In vibe coding, they are made silently by a tool optimized to produce something that works right now.
That is why you feel like you do not know what you do not know. It is not a lack of intelligence. It is not imposter syndrome. It is an accurate reading of the situation. The tool you are using is specifically designed to handle complexity on your behalf without surfacing it. You cannot see what you are missing because the AI made it invisible.
What Is Actually Hiding
Let me make this concrete. When people come to me and say “I don’t know what I don’t know,” they are usually sitting on top of real, specific gaps they have no reason to be aware of. These are not theoretical risks. They are the things that actually break when vibe-coded apps move from development to the real world.
Here are four categories that come up consistently.
Security. This is the big one. AI-generated code tends to optimize for “does this work?” rather than “is this safe?” The patterns are consistent: missing input validation, API keys or credentials embedded in client-side code, authentication logic that can be bypassed, and access controls that look correct but are not actually enforced. These are not rare edge cases. A December 2025 analysis of hundreds of open-source pull requests found that AI co-authored code had significantly more major issues than human-written code, including security vulnerabilities at nearly three times the rate. In early 2026, researchers examined over 1,600 apps built with a popular vibe coding platform and found that more than ten percent had critical security flaws in their database configurations. One startup built entirely with AI coding tools had to shut down after users discovered they could bypass all paid features by changing a single value in the browser console. The security logic was implemented entirely on the client side, which is one of the most common mistakes AI makes, and the founder had no way to know that was a problem.
If you have not thought about security in your app, that does not mean your app is insecure. But it probably means you do not know whether it is secure, and those are very different situations.
Reliability. Your app works when you test it. You are one person, on a good internet connection, entering reasonable data, doing things in the expected order. Production is different. Real users do unexpected things. They double-click buttons. They submit empty forms. They leave a tab open for three days and come back. They have slow connections. Two of them try to edit the same record at the same time. Your app needs to handle all of this without breaking, losing data, or showing cryptic error messages. AI-generated code rarely accounts for these scenarios unless you specifically ask. It builds for the happy path, because the happy path is what you described.
Data integrity. How your app stores, retrieves, and protects data is foundational, and it is almost entirely invisible during development. Questions like: what happens if a database write fails halfway through? Can one user see another user’s data? What happens when storage limits are reached? Is sensitive information being logged somewhere it should not be? Are there backups? These are decisions that were either made for you (often badly) or not made at all. You will not discover the problem until data is lost, exposed, or corrupted, and by then the damage is done.
Operational readiness. This is everything that matters once real people are using your app. Can you tell when something goes wrong? Do you have logging that shows you what happened? Can you deploy updates without taking the app down? What happens if a service your app depends on has an outage? Is there a way to roll back a bad change? Most vibe-coded apps have no observability, no deployment discipline, and no plan for when things go wrong. They work until they do not, and when they stop working, there is no way to figure out why.
None of this is meant to make you feel bad about what you have built. Every one of these gaps is normal. Professional software teams spend years developing practices to address them. The point is not that you should have known about these things already. The point is that now you know they exist, they stop being invisible.
The Real Problem Is Not the Gap. It Is Staying in It.
Here is what I have seen in hundreds of conversations: the people who struggle are not the ones who have knowledge gaps. Everyone has knowledge gaps. The people who struggle are the ones who stay in “I don’t know what I don’t know” without taking the next step.
That next step is not “learn everything about software engineering.” That would take years, and most of it would not be relevant to what you are building. The next step is much simpler: find out what you specifically do not know about your specific project, so you can make informed decisions about what to learn and what to address.
The path from “I don’t know what I don’t know” has three stages, and the good news is that the first two are short.
Stage one is where you are now: “I don’t know what I don’t know.” This feels overwhelming because the space of possible problems is infinite.
Stage two is: “I know what I don’t know.” This feels manageable because you have a finite list. You can see the specific decisions and gaps in your project. You might not understand them yet, but you can see them. You know what to research, what to ask about, and what to prioritize.
Stage three is: “I know enough about the things that matter for my project.” Not everything. Not a computer science degree. Just enough understanding of the specific concepts that affect your specific app, so you can make conscious decisions instead of hoping for the best.
The jump from stage one to stage two is the most important one. And you can make it in an afternoon.
Turning the Unknown into a List
This is where having a practical method matters. I wrote an article introducing a framework called Surface, Explore, Record, and I am building a YouTube series around it that walks through applying it to a real app build. The basic idea is straightforward, and it directly addresses the “I don’t know what I don’t know” problem.
The first step, Surface, is specifically designed to convert that overwhelming feeling into a concrete list. You ask AI to surface the decisions that exist in your project (or that need to be made before you start building). Not to fix anything. Not to evaluate anything. Just to make the invisible visible.
The prompt can be as simple as: “Look at my app. What decisions were made during development that I should understand before putting real users on this? List them. Don’t fix anything. Just tell me what exists.”
What comes back is a list. Suddenly the infinite space of “things I might not know” becomes a finite set of specific decisions and gaps. Some of them you will understand immediately. Others you will need to explore. But the shape of the problem is now visible, which is a completely different emotional and practical situation than the one you were in five minutes ago.
The second step, Explore, is where you work through that list. For each decision, you ask AI to explain your options, what each approach is good at, what each one struggles with, and what the tradeoffs are. You do not need to understand every technical detail. You need to understand enough to make a choice that fits your situation. “This approach is simpler but will not handle more than a few hundred users at once” is information you can act on. You know whether you are building for ten people or ten thousand.
The third step, Record, is where you write down what you decided and why. This might sound tedious, but it pays off immediately. When something breaks later, you are not guessing at decisions made weeks ago. When you want to add a feature, you know what constraints you are working within. And here is the part that surprises people: you can give your recorded decisions back to AI. Instead of AI guessing at your architecture, it has your actual decisions. Its suggestions become dramatically more useful because they fit your real situation instead of a generic one.
The framework turns “I don’t know what I don’t know” into “here are the twenty decisions in my app, I have explored my options for each one, and I have chosen consciously.” That is a different relationship with your project entirely.
You Do Not Need to Learn Everything
One of the most common things I hear in consultations, right after “I don’t know what I don’t know,” is something like: “I feel like I need to go learn software engineering from scratch before I can move forward.”
You do not.
What you need is targeted knowledge about the concepts that matter for what you are building. If your app handles user data, you need to understand authentication and authorization. If it processes payments, you need to understand error handling and idempotency. If it needs to stay running reliably, you need to understand logging and deployment discipline.
You do not need to learn all of these before you build anything. You need to learn the ones that are relevant to your project, and you need to learn them well enough to make informed decisions. That is a very different scope than “learn software engineering.”
This is why I wrote the Engineering for Vibe Coders series. Each article covers one foundational concept that professional engineers rely on every day, explained for people who are building with AI. No lengthy code tutorials. No computer science theory. Just the practical understanding you need to make better decisions about your project.
The series is organized by category (foundations, reliability, execution, infrastructure, testing, observability and security), but you do not need to work through it in order. Start with whatever is most relevant to your situation. If you surfaced decisions about your app and one of them involves error handling, read the error handling article. If you realized your app has no logging, read the logging article. The framework tells you what to learn. The series teaches it.
What Makes This Moment Different
A year ago, if you wanted to build a real application, you needed to either learn to code or hire someone who could. Now you can go from idea to working prototype in an afternoon. That is genuinely new. That is worth being excited about.
But the skills that make software production-ready have not changed. Security still matters. Reliability still matters. Understanding what your app is doing and why still matters. The difference is that the path to those skills looks different now. You are not learning them as prerequisites before you can build anything. You are learning them as you go, guided by the real needs of a real project.
That is actually a better way to learn. The concepts are not abstract. They are answers to specific questions about something you care about. “How should my app handle it when a user submits bad data?” is a much more motivating question than “explain input validation in the abstract.”
The people I talk to in consultations who are making the fastest progress are not the ones with the most technical background. They are the ones who took the step from “I don’t know what I don’t know” to “I know what I need to learn next.” They surfaced the decisions in their projects. They started exploring their options. They began making conscious choices instead of hoping AI got it right.
Every single one of them started exactly where you are.
Where to Start
If you are reading this and recognizing yourself, here is what I would suggest.
First, accept that “I don’t know what I don’t know” is not a failing. It is an accurate and honest assessment of where you are, and it puts you ahead of anyone who assumes their AI-generated app is fine because it runs.
Second, get specific. Take whatever you are building (or planning to build) and use the Surface, Explore, Record framework to turn the vague anxiety into a concrete list. The article and YouTube series walk through exactly how to do this, step by step, on a real project.
Third, prioritize. You do not need to address every gap at once. If your app handles user data, security comes first. If you are about to deploy, operational readiness comes first. If things keep breaking when you add features, architecture comes first. Pick the thing that matters most for your situation right now.
Fourth, learn that one thing well enough to make a decision about it. The Engineering for Vibe Coders series is there for that. So is the consultation if you want someone to help you identify what matters most for your specific project.
The distance between “I don’t know what I don’t know” and “I know what I’m building and why it works this way” is shorter than you think. It is not a years-long journey through a computer science curriculum. It is a series of specific questions about your specific project, answered one at a time.
You already took the hardest step. You noticed the gap. Now you just need to look at what is in it.
Here’s some additional help:
The Planning Room for AI Decisions
Surface, Explore, Record Framework Description
Surface, Explore, Record YouTube Series
Engineering for Vibe Coders Series
Free 30 minute consultations
