Model life cycle

This has been driving me nuts all day Here’s my stripped out plugin

class BaseProjectPlugin implements Plugin<Project> {
    void apply(Project project) {
        
        project.plugins.apply(ProjectMetadataRules)

        // *** validate the build file ***
        project.afterEvaluate {
            project.with {
                model {
                    projectMetadata {
                        println "projectHash: $projectHash"

                        if (projectHash == null) {
                            throw new InvalidUserDataException(NON_CONFIG_ERROR)
                        }
                    }
                }
            }
        }
    }
}

build.gradle file

model {
    projectMetadata {
        projectHash = 'ab345678'
    }
}

The problem is when i test this, the println "projectHash: $projectHash" of the plugin always prints the default value (null). but when i run the models task, it prints out the correct value. Am i missing something in the lifecycle here?