Skip to content

avoid_constant_switches

v0.4.0 Warning Control Flow

Flags a switch statement or switch expression whose subject is a compile-time constant. The value never changes, so one case always wins and every other case is unreachable.

Switching on the constant rather than on the value it was meant to be compared with:

abstract final class Config {
static const channel = 'stable';
}
String bannerText() {
switch (Config.channel) {
case 'stable':
return 'Welcome';
case 'beta':
return 'Thanks for testing'; // Unreachable
default:
return ''; // Unreachable
}
}

Switch on something that varies at runtime:

abstract final class Config {
static const channel = 'stable';
}
String bannerText(String channel) {
switch (channel) {
case 'stable':
return 'Welcome';
case 'beta':
return 'Thanks for testing';
default:
return '';
}
}

If the value really is fixed, you did not need a switch — say what you meant:

abstract final class Config {
static const channel = 'stable';
}
String bannerText() => 'Welcome';

The rule registers both forms, so an expression switch on a literal reports the same way:

void demo() {
// Don't
final label = switch (42) {
42 => 'answer',
_ => 'other',
};
}

Status.active is a const field on the enum, so switching on it takes the same fixed branch every time:

enum Status { active, archived }
void demo() {
// Don't — switch on the value, not on the constant you are testing for
switch (Status.active) {
case Status.active:
print('live');
case Status.archived:
print('gone');
}
}

Switching on order.status reads a property and is never reported.

The diagnostic lands on the switch subject, not on the whole statement, so the highlight points at the expression you need to change.

Constness is read syntactically: literals, const variables and static const fields (enum constants included), const collections and const constructor calls. A plain final local is not treated as constant — final mode = 'debug'; switch (mode) is not reported. Neither is a method call, so switch (buildMode()) stays silent even when the function always returns the same thing.

There is no quick fix: replacing the subject with the right variable is the design decision the rule is asking about.

This rule is in the core preset, so it is on with preset: core, preset: recommended or preset: opinionated.

To turn it off:

many_lints.yaml
rules:
avoid_constant_switches: false

To keep the rule on but skip certain paths, use per-rule exclude.