skip to content

Which Flutter code changes does hot reload reject or fail to apply, and what do you do instead for each?

level: middleimportance: should knowfreq 32%

answer

  1. existing objects must stay valid
  2. enum to class, class to enum
  3. adding a type parameter
  4. native code needs full restart
  5. Try performing a hot restart instead

basics

~20 s

Hot reload rejects turning an enum into a class or back and changing a class's generic type parameters, so hot restart. It cannot see native Kotlin or Swift edits or new platform plugins, which need a full restart, and it waits for compile errors to be fixed.

solid answer

~40 s

Hot reload patches a running VM while keeping existing objects, so it refuses edits that would invalidate them. Changing an `enum` to a class or a class to an `enum`, or changing a class's type parameters (`A<T>` to `A<T, V>`), makes the tool print that the reload was rejected with the hint "Try performing a hot restart instead", and a hot restart recreates everything with the new definitions. Compilation errors block the reload until fixed. Native edits in Kotlin, Java, Swift or Objective-C, including a newly added plugin with platform code, are outside the VM and need a full restart. The docs also note that hot reload does not apply changes to `CupertinoTabView`'s `builder`.

code

dart · 8 lines
dart
// Before: running with this enum, then hot reload after the edit below.
enum CallQuality { low, medium, high }

// After: the same name as a class. Hot reload is rejected; hot restart works.
class CallQuality {
  const CallQuality(this.bitrateKbps);
  final int bitrateKbps;
}

go deeper

for a junior

Remember the short list: enum-class swaps and generic changes need a hot restart, native code needs a full restart.

for a middle

Explain why these edits are rejected: hot reload keeps existing objects, and these changes would leave them with an impossible shape.

for a senior

Read the rejection reason, choose restart versus full restart immediately, and plan model refactors so the team restarts once rather than repeatedly.

for a principal

Keep native changes and structural model changes in small, deliberate steps so day-to-day work stays in the fast hot-reload loop.

## Two kinds of failure When a Flutter edit does not take effect with hot reload, there are two very different situations: - **Applied but invisible**: the reload succeeds, but the edited code does not run again (`main()`, `initState()`, static initializers). That is a question of state. - **Rejected or not applicable**: the reload cannot apply the change at all, and the tool reports an error or the change is silently ignored. That is a question of **what the running program can absorb**. This answer is about the second kind. ## Changes that stop a reload When hot reload runs, the tool recompiles the changed libraries and the Dart VM tries to swap them in **while keeping existing objects alive**. Some edits would make existing objects meaningless, so the VM refuses the reload and the tool prints `Hot reload was rejected:` or `Hot reload failed:` followed by the reasons, each with the suggestion `Try performing a hot restart instead.` The Flutter documentation lists these cases: | Edit | Example | Why it cannot be reloaded | |---|---|---| | Enum to class, or class to enum | `enum Color { red, green, blue }` becomes `class Color { ... }` | Existing values were created as enum instances with a fixed set of constants | | Changing generic type parameters | `class A<T>` becomes `class A<T, V>` | Live instances were created with the old number of type arguments | | Compilation errors | Unbalanced braces | Nothing can be loaded until the code compiles | Compilation errors are the easy one: fix the reported line and reload again. For the structural changes, a **hot restart** is the remedy, because it recreates every object from scratch with the new definitions. ## Changes hot reload cannot see Some edits are outside the Dart VM entirely: - **Native code.** Kotlin, Java, Swift or Objective-C in the host project needs a **full restart**, meaning stop and run again, because only a fresh build compiles it. - **New plugins with platform code.** Adding such a dependency brings native code with it, so the same rule applies. - **`CupertinoTabView`'s `builder`.** The docs record that hot reload does not apply changes made to this builder (a known framework issue); hot restart does. ## When the app itself is gone Hot reload needs a live connection to a running debug app. If the OS killed the app, for example after it sat in the background too long, hot reload breaks and you need to run it again. ## Reading the error A rejected reload is **not** a problem with your code; the program is valid, it just cannot be patched in place. Good habits: 1. Read the reason line: it names the class or declaration that changed shape. 2. Hot restart rather than retrying hot reload. 3. When renaming or reshaping a model class used across the app (turning an `enum` into a sealed class hierarchy, adding a type parameter), expect a restart and plan the edit so you do it once. 4. If the console shows nothing but the UI ignores native changes, check whether you edited platform code and do a full restart. ## Web hot reload On the web, hot reload has been on by default since Flutter 3.35. There, rejections happen when the change is compiled rather than inside a running VM, but the practical remedy is the same: hot restart. ## Summary - **Rejected** (restart fixes it): enum-class swaps, generic parameter changes. - **Blocked** until fixed: compilation errors. - **Invisible to hot reload** (full restart): native code and new platform plugins. - **Known exception** (hot restart): `CupertinoTabView.builder`.

  • Is a rejected hot reload a sign that the code is wrong?
    No. The program can be perfectly valid; it just cannot be patched into objects that already exist. The reason line names the declaration that changed shape, and a hot restart applies the same code cleanly.
  • You converted an enum into a sealed class hierarchy for a model. Which dev-loop action applies it?
    A hot restart. Turning an `enum` into classes is one of the documented cases hot reload rejects, because existing values were enum instances. A hot restart rebuilds every object from the new definitions.

saying these in an interview costs you the question

  • A rejected hot reload means the code will not compile.
  • Adding a type parameter to a class hot reloads like any other edit.
  • Native Kotlin changes are picked up by a hot restart.
  • Hot reload can convert live enum values into class instances.
  • If hot reload fails, the only fix is to reinstall the app.