Code review comment: ⛏️ Shall we also say around line 1170 that the first iteration always gets defined here?  I suggest this because this comment only says do not skip but not the reason but still programmers have to read the code and identify why it is saying not to skip.

Code under review:
private void defineTypeNodes(List<BLangNode> typeDefs, SymbolEnv env) {
        if (typeDefs.isEmpty()) {
            return;
        }

        this.unresolvedTypes = new ArrayList<>(typeDefs.size());
        this.unresolvedRecordDueToFields = new HashSet<>(typeDefs.size());
        this.resolveRecordsUnresolvedDueToFields = false;
        for (BLangNode typeDef : typeDefs) {
            if (isErrorIntersectionTypeCreatingNewType(typeDef, env)) {
                populateUndefinedErrorIntersection((BLangTypeDefinition) typeDef, env);
                continue;
            }

            defineNode(typeDef, env);
        }

        if (typeDefs.size() <= unresolvedTypes.size()) {

            this.resolveRecordsUnresolvedDueToFields = true;
            unresolvedTypes.removeAll(unresolvedRecordDueToFields);
            for (BLangNode unresolvedType : unresolvedRecordDueToFields) {
                defineNode(unresolvedType, env);
            }
            this.resolveRecordsUnresolvedDueToFields = false;

            
            
            

            for (BLangNode unresolvedType : unresolvedTypes) {
                Stack<String> references = new Stack<>();
                NodeKind unresolvedKind = unresolvedType.getKind();
                if (unresolvedKind == NodeKind.TYPE_DEFINITION || unresolvedKind == NodeKind.CONSTANT) {
                    TypeDefinition def = (TypeDefinition) unresolvedType;
                    
                    references.push(def.getName().getValue());
                    checkErrors(env, unresolvedType, (BLangNode) def.getTypeNode(), references, false);
                } else if (unresolvedType.getKind() == NodeKind.CLASS_DEFN) {
                    BLangClassDefinition classDefinition = (BLangClassDefinition) unresolvedType;
                    references.push(classDefinition.getName().getValue());
                    checkErrors(env, unresolvedType, classDefinition, references, true);
                }
            }
            defineAllUnresolvedCyclicTypesInScope(env);

            Set<String> alreadyDefinedTypeDefNames = new HashSet<>();
            int unresolvedTypeCount = unresolvedTypes.size();
            for (int i = 0; i < unresolvedTypeCount; i++) {
                for (BLangNode node : this.unresolvedTypes) {
                    String name = getTypeOrClassName(node);
                    boolean symbolNotFound = false;
                    if ((node.getKind() == NodeKind.TYPE_DEFINITION || node.getKind() == NodeKind.CLASS_DEFN)
                            && i != 0) { 
                        BSymbol bSymbol = symResolver.lookupSymbolInMainSpace(env, names.fromString(name));
                        symbolNotFound = (bSymbol == symTable.notFoundSymbol);
                    }

                    boolean notFoundInList = alreadyDefinedTypeDefNames.add(name);

                    
                    if (notFoundInList || symbolNotFound) {
                        defineNode(node, env);
                    }
                }
            }
            return;
        }
        defineTypeNodes(unresolvedTypes, env);
    }

Line commented on: && i != 0) {

Revised code:
private void defineTypeNodes(List<BLangNode> typeDefs, SymbolEnv env) {
        if (typeDefs.isEmpty()) {
            return;
        }

        this.unresolvedTypes = new ArrayList<>(typeDefs.size());
        this.unresolvedRecordDueToFields = new HashSet<>(typeDefs.size());
        this.resolveRecordsUnresolvedDueToFields = false;
        for (BLangNode typeDef : typeDefs) {
            if (isErrorIntersectionTypeCreatingNewType(typeDef, env)) {
                populateUndefinedErrorIntersection((BLangTypeDefinition) typeDef, env);
                continue;
            }

            defineNode(typeDef, env);
        }

        if (typeDefs.size() <= unresolvedTypes.size()) {

            this.resolveRecordsUnresolvedDueToFields = true;
            unresolvedTypes.removeAll(unresolvedRecordDueToFields);
            for (BLangNode unresolvedType : unresolvedRecordDueToFields) {
                defineNode(unresolvedType, env);
            }
            this.resolveRecordsUnresolvedDueToFields = false;

            
            
            

            for (BLangNode unresolvedType : unresolvedTypes) {
                Stack<String> references = new Stack<>();
                NodeKind unresolvedKind = unresolvedType.getKind();
                if (unresolvedKind == NodeKind.TYPE_DEFINITION || unresolvedKind == NodeKind.CONSTANT) {
                    TypeDefinition def = (TypeDefinition) unresolvedType;
                    
                    references.push(def.getName().getValue());
                    checkErrors(env, unresolvedType, (BLangNode) def.getTypeNode(), references, false);
                } else if (unresolvedType.getKind() == NodeKind.CLASS_DEFN) {
                    BLangClassDefinition classDefinition = (BLangClassDefinition) unresolvedType;
                    references.push(classDefinition.getName().getValue());
                    checkErrors(env, unresolvedType, classDefinition, references, true);
                }
            }
            defineAllUnresolvedCyclicTypesInScope(env);

            Set<String> alreadyDefinedTypeDefNames = new HashSet<>();
            int unresolvedTypeCount = unresolvedTypes.size();
            for (int i = 0; i < unresolvedTypeCount; i++) {
                for (BLangNode node : this.unresolvedTypes) {
                    String name = getTypeOrClassName(node);
                    boolean symbolNotFound = false;
                    boolean isTypeOrClassDefinition =
                            node.getKind() == NodeKind.TYPE_DEFINITION || node.getKind() == NodeKind.CLASS_DEFN;
                    
                    
                    if (isTypeOrClassDefinition && i != 0) { 
                        BSymbol bSymbol = symResolver.lookupSymbolInMainSpace(env, names.fromString(name));
                        symbolNotFound = (bSymbol == symTable.notFoundSymbol);
                    }

                    boolean notFoundInList = alreadyDefinedTypeDefNames.add(name);

                    
                    if (notFoundInList || symbolNotFound) {
                        defineNode(node, env);
                    }
                }
            }
            return;
        }
        defineTypeNodes(unresolvedTypes, env);
    }