diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp
index 1f95ad948..36c88dad1 100644
--- a/src/query/frontend/ast/ast.hpp
+++ b/src/query/frontend/ast/ast.hpp
@@ -1105,6 +1105,8 @@ class MapProjectionLiteral : public memgraph::query::BaseLiteral {
   DEFVISITABLE(ExpressionVisitor<void>);
   bool Accept(HierarchicalTreeVisitor &visitor) override {
     if (visitor.PreVisit(*this)) {
+      map_variable_->Accept(visitor);
+
       for (auto pair : elements_) {
         if (!pair.second) continue;
 
diff --git a/src/query/interpret/eval.hpp b/src/query/interpret/eval.hpp
index 1c78d6c9b..39e6a7c5f 100644
--- a/src/query/interpret/eval.hpp
+++ b/src/query/interpret/eval.hpp
@@ -763,20 +763,27 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
 
     TypedValue::TMap result(ctx_->memory);
     TypedValue::TMap all_properties_lookup(ctx_->memory);
+
+    auto map_variable = literal.map_variable_->Accept(*this);
+    if (map_variable.IsNull()) {
+      return TypedValue(ctx_->memory);
+    }
+
     for (const auto &[property_key, property_value] : literal.elements_) {
       if (property_key.name == kAllPropertiesSelector.data()) {
         auto maybe_all_properties_lookup = property_value->Accept(*this);
 
         if (maybe_all_properties_lookup.type() != TypedValue::Type::Map) {
-          throw QueryRuntimeException("Expected a map from AllPropertiesLookup, got {}.",
-                                      maybe_all_properties_lookup.type());
+          LOG_FATAL("Expected a map from AllPropertiesLookup, got {}.", maybe_all_properties_lookup.type());
         }
+
         all_properties_lookup = std::move(maybe_all_properties_lookup.ValueMap());
         continue;
       }
 
       result.emplace(property_key.name, property_value->Accept(*this));
     }
+
     if (!all_properties_lookup.empty()) result.merge(all_properties_lookup);
 
     return TypedValue(result, ctx_->memory);
diff --git a/src/query/plan/rule_based_planner.cpp b/src/query/plan/rule_based_planner.cpp
index 65e4361e1..c02a7eaa6 100644
--- a/src/query/plan/rule_based_planner.cpp
+++ b/src/query/plan/rule_based_planner.cpp
@@ -98,6 +98,11 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
     auto it = has_aggregation_.end();
     auto elements_it = literal.elements_.begin();
     std::advance(it, -literal.elements_.size());
+    if (literal.GetTypeInfo() == MapProjectionLiteral::kType) {
+      // Erase the map variable. Grammar-wise, it’s a variable and thus never has aggregations.
+      std::advance(it, -1);
+      it = has_aggregation_.erase(it);
+    }
     while (it != has_aggregation_.end()) {
       if (*it) {
         has_aggr = true;
@@ -446,9 +451,9 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
   std::vector<Expression *> group_by_;
   std::unordered_set<Symbol> group_by_used_symbols_;
   // Flag stack indicating whether an expression contains an aggregation. A
-  // stack is needed so that we differentiate the case where a child
-  // sub-expression has an aggregation, while the other child doesn't. For
-  // example AST, (+ (sum x) y)
+  // stack is needed to address the case where one child sub-expression has
+  // an aggregation, while the other child does not.
+  // For example, the AST (+ (sum x) y) is as follows:
   //   * (sum x) -- Has an aggregation.
   //   * y -- Doesn't, we need to group by this.
   //   * (+ (sum x) y) -- The whole expression has an aggregation, so we don't
diff --git a/tests/gql_behave/tests/memgraph_V1/features/map_projection.feature b/tests/gql_behave/tests/memgraph_V1/features/map_projection.feature
index f04b04a6e..da20f2856 100644
--- a/tests/gql_behave/tests/memgraph_V1/features/map_projection.feature
+++ b/tests/gql_behave/tests/memgraph_V1/features/map_projection.feature
@@ -4,7 +4,7 @@ Feature: Map projection
     When executing query:
       """
       WITH {} AS map
-      RETURN map {} as result
+      RETURN map {} AS result
       """
     Then the result should be:
       | result |
@@ -26,6 +26,17 @@ Feature: Map projection
       | result                                                    |
       | {age: 85, lastName: 'Freeman', name: 'Morgan', oscars: 1} |
 
+  Scenario: Projecting from a null value
+    When executing query:
+      """
+      WITH "value" AS var
+      OPTIONAL MATCH (n:Nonexistent)
+      RETURN n {.*} AS result0, n {.prop} AS result1, n {prop: "value"} AS result2, n {var} AS result3;
+      """
+    Then the result should be:
+      | result0 | result1 | result2 | result3 |
+      | null    | null    | null    | null    |
+
   Scenario: Projecting a nonexistent property
     When executing query:
       """