Dart's Analyzer missed required parameters

When working with Dart, developers expect the compiler and analyzer to catch null-related issues at compile time. However, there are cases where the Dart analyzer can miss nullability checks, allowing code that may compile successfully but throw errors at runtime.

Let's look at a code snippet that compiles but fails at runtime:

abstract class EndPoint {
  final String path;
  final String method;
  final Map<String, dynamic> headers;
  final Map<String, dynamic> queryParameters;
  final Map<String, dynamic> body;

  EndPoint({
    this.path,
    this.method,
    this.headers,
    this.queryParameters,
    this.body,
  });

  void execute() {
    print('Executing endpoint');
  }
}

The problem

In this class, headers, queryParameters, and body are declared as non-nullable Map<String, dynamic> fields. But they don’t have default values or required markers, they implicitly default to null. Dart’s analyzer doesn’t catch this issue during compilation, which leads to the following runtime error:

Error: The parameter 'headers' can't have a value of 'null' because of its type 'Map<String, dynamic>', but the implicit default value is 'null'.

A solution would be to explicitly declare these parameters as required, as shown below:

A solution would be explicitly declare these parameters as required:

EndPoint({
    required this.path,
    required this.method,
    this.headers = const {},
    this.queryParameters = const {},
    this.body = const {},
});

The analyzer may not catch every null-safety issue.