          for key, migration in normal.items():
              for parent in migration.dependencies:
                  reverse_dependencies.setdefault(parent, set()).add(key)
          # Carry out replacements if we can - that is, if all replaced migrations
          # are either unapplied or missing.
          for key, migration in replacing.items():
              # Ensure this replacement migration is not in applied_migrations
 
</s> remove                 self.graph.add_dependency(migration, key, parent)
 </s> add                 try:
                    self.graph.add_dependency(migration, key, parent)
                except NodeNotFoundError as e:
                    # Since we added "key" to the nodes before this implies
                    # "parent" is not in there. To make the raised exception
                    # more understandable we check if parent could have been
                    # replaced but hasn't (eg partially applied squashed
                    # migration)
                    _reraise_missing_dependency(migration, parent, e) </s> remove                     self.graph.add_dependency(migration, key, parent)
 </s> add                     try:
                        self.graph.add_dependency(migration, key, parent)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "parent" is not in there.
                        _reraise_missing_dependency(migration, parent, e) </s> remove                     self.graph.add_dependency(migration, child, key)
 </s> add                     try:
                        self.graph.add_dependency(migration, child, key)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "child" is not in there.
                        _reraise_missing_dependency(migration, child, e) </s> remove         "Gets the migration exactly named, or raises KeyError"
 </s> add         "Gets the migration exactly named, or raises `graph.NodeNotFoundError`" </s> remove             raise ValueError("Node %r not a valid node" % (node, ))
 </s> add             raise NodeNotFoundError("Node %r not a valid node" % (node, ), node)
        # Remeber the possible replacements to generate more meaningful error
        # messages
        reverse_replacements = {}
        for key, migration in replacing.items():
            for replaced in migration.replaces:
                reverse_replacements.setdefault(replaced, set()).add(key)
          for key, migration in normal.items():
              for parent in migration.dependencies:
                  reverse_dependencies.setdefault(parent, set()).add(key)
        # Remeber the possible replacements to generate more meaningful error
        # messages
        reverse_replacements = {}
        for key, migration in replacing.items():
            for replaced in migration.replaces:
                reverse_replacements.setdefault(replaced, set()).add(key)
          # Carry out replacements if we can - that is, if all replaced migrations
          # are either unapplied or missing.
          for key, migration in replacing.items():
              # Ensure this replacement migration is not in applied_migrations
keep keep add keep keep keep keep
 Fixed #23556 -- Raised a more meaningful error message when migrations refer to an unavailable node 
django/db/migrations/loader.py