I Trusted Dart’s Null Safety… and It Still Crashed My App

Table of contents
- What Is Null Safety, Really?
- What I Did Wrong: The Dangerous! Operator
- Let’s Break Down the Null Safety Tools
- ? → Nullable Variable
- ! → Null Assertion
- late → Delayed Initialization
- required → Non-nullable named parameters
- Real-World Use Case: User Profile Model
- Best Practices for Null Safety in Dart
- Extra Tip: Null-Aware Operators in Dart
- ?? → Default value if null
- ??= → Assign default if null
- ?. → Safe access
- Final Thoughts
- My Advice to You
- I’d love to hear from you:

It was a chill Thursday night. I was working on a profile update feature for one of my Flutter apps. I had just refactored a bunch of code and felt pretty confident.
After all, Dart has null safety now what could go wrong?
The app launched, everything looked good. But then… Crash.
Not a red screen. Not a console warning. A full-on, “Unhandled exception: Null check operator used on a null value.”
I was confused.
“Wait, I’m using null safety. Isn’t this stuff supposed to be impossible now?”
I had sprinkled a few !
operators here and there (you know, just to keep the compiler happy). But that one exclamation mark brought the whole thing down.
That was my wake-up call.
And that night, I went deep into understanding Dart’s null safety. In this post, I’ll share:
What I did wrong
How Dart null safety really works
What tools Dart gives you (
?
,!
,late
,required
)Best practices to keep your app safe, clean, and crash-free
What Is Null Safety, Really?
Null safety in Dart means you have to explicitly declare when a variable can be null.
Before null safety, any variable could potentially be null, leading to tons of runtime crashes.
Now, you write:
String name = 'Md. Al-Amin'; // non-nullable
String? nickname; // nullable
Dart forces you to think about nulls. It doesn’t let you do:
print(nickname.length); // ❌ compile error
You need to check if it’s null:
if (nickname != null) {
print(nickname.length);
}
Or use !
to say “I promise this isn’t null” (but use it carefully… more on that soon).
What I Did Wrong: The Dangerous! Operator
Back to my bug…
I had this code:
String? userToken;
// later...
apiClient.setToken(userToken!);
In my head, I was sure userToken
was initialized before calling setToken
. But in reality, it wasn’t.
That !
is called the null assertion operator, and it basically says:
“Trust me, this is not null don’t check, just run.”
But Dart doesn’t protect you here. If userToken
is null, you crash.
And that’s exactly what happened.
Let’s Break Down the Null Safety Tools
?
→ Nullable Variable
String? email;
This means email
can be either a String
or null
.
Use ?
when:
You’re receiving data from external sources (APIs, storage, etc.)
A variable truly might not be set (optional fields)
!
→ Null Assertion
String? email;
print(email!); // You better be 100% sure it's not null
Use this only when you’re absolutely certain a value can never be null at that point.
When it’s okay:
if (email != null) {
print(email!); // you're safe here
}
When it’s dangerous:
print(email!.length); // if email is null = crash!
Tip: Avoid using !
unless you’ve done a prior null check.
late
→ Delayed Initialization
What if a variable can’t be set immediately, but you’re sure it’ll be set before use?
late String token;
void init() {
token = fetchToken();
}
void makeRequest() {
print(token); // Dart assumes it's set before use
}
If you forget to assign it before access Dart throws an error at runtime.
Use late
when:
You want to avoid
null
, but initialize later (e.g., ininitState
)You’re working with dependency injection
Don’t use it as a lazy shortcut for avoiding ?
or !
.
required
→ Non-nullable named parameters
Before null safety:
void createUser(String name, String email);
After null safety:
void createUser({required String name, required String email});
If the caller doesn’t pass name
or email
, Dart throws a compile-time error.
Use required
for:
Named parameters that are essential
Enforcing contracts in your API or widget constructors
Real-World Use Case: User Profile Model
Let’s look at a simple User
model that could crash if nulls aren’t handled well:
class User {
final String name;
final String? email;
final String? phone;
User({
required this.name,
this.email,
this.phone,
});
}
Now, when rendering UI:
Text(user.email ?? 'No email available'),
That’s safe. No !
needed. No risk of crash.
Best Practices for Null Safety in Dart
Here’s what I learned and now live by:
Do This
Use
?
when data may be nullUse
required
for essential fieldsCheck nulls before using values
Use defaults like
??
Write unit tests for null cases
Avoid This
Making everything
late
to avoid?
Forcing values with
!
everywhereTrusting external data blindly
Assuming things are initialized
Ignoring edge cases in models
Extra Tip: Null-Aware Operators in Dart
Dart gives you some powerful operators:
??
→ Default value if null
print(user.email ?? 'No email');
??=
→ Assign default if null
email ??= 'unknown@example.com';
?.
→ Safe access
print(user.profile?.bio); // If profile is null, won’t crash
Final Thoughts
Dart’s null safety is amazing, but it only works if we understand how to use it.
Null safety doesn’t mean “no more crashes.”
It means: “You now have the power to prevent them, but you have to think.”
My Advice to You
Avoid the
!
unless you’re absolutely sureUse
?
and null-aware operators liberally they’re your friendsDon’t go overboard with
late
— it’s powerful, but sharpAnd always, always test your edge cases
If Dart asks you to handle nulls, it’s not being annoying its saving future you from a nightmare.
I’d love to hear from you:
Have you ever been betrayed by a !
? Or misused late
and got runtime surprises?
Share your experience and let’s help each other write safer Dart code.
Subscribe to my newsletter
Read articles from Md. Al - Amin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Md. Al - Amin
Md. Al - Amin
Experienced Android Developer with a demonstrated history of working for the IT industry. Skilled in JAVA, Dart, Flutter, and Teamwork. Strong Application Development professional with a Bachelor's degree focused in Computer Science & Engineering from Daffodil International University-DIU.