Passing regular files only to `sed -i`

It's normal behavior. In both cases sed exits with error code 4... per info sed:

4
     An I/O error, or a serious processing error during runtime,
     GNU 'sed' aborted immediately.

and in both cases the messages are self-explanatory. Not sure what's unclear but for the record: the first time it errors out because it cannot edit a directory and the second time it complains because it cannot edit stdin in-place, it needs a file (i.e. remove that redirect before $file)
The proper way to do this with find is, as you noted, via -exec ...
With globs, you'll have to use a loop and test if input is a regular file before running sed. Or, if you're a zsh user, you can simply do:

sed -i 's/foo/bar/g' *(.)

  • Case 2:

    Avoid that directory with find:

      sed -i 's/foo/bar/g' $(find . -maxdepth 1 -type f)
    
  • Case 3:

    The problem is the <"$file" in the loop, that turns the file into a stream so sed never sees a filename. Just remove that <:

      for file in $(find . -maxdepth 1 -type f); do 
          sed -i 's/foo/bar/g' "$file"
      done