invalid argument in foreach when trying to list custom post types in archive.php

get_pages() is intended only for hierarchical post types like page. For non-hierarchical post types like post, get_pages() will return a false, hence that explains why get_pages( array( 'post_type' => 'post' ) ) “doesn’t work”, i.e. the returned value is not an array, so it can’t be used with foreach:

// Good: 'page' is a hierarchical post type.
$pages = get_pages( array( 'post_type' => 'page' ) );
// Output: $pages is an array. Can do foreach ( $pages ... )

// Not good: 'post' is a non-hierarchical post type.
$posts = get_pages( array( 'post_type' => 'post' ) );
// Output: $posts is a FALSE. Can't do foreach ( $posts ... )
// because foreach ( false ... ) is invalid.

So for non-hierarchical post types, you would use get_posts() or make a new instance of WP_Query (i.e. new WP_Query()):

$posts = get_posts( array( 'post_type' => 'post' ) );

// or..
$query = new WP_Query( array( 'post_type' => 'post' ) );
$posts = $query->posts;