I think there's some confusion throughout this thread as to what "harm" entails. If you define harm as (merely) "does OP's exact code operate properly?", then it's not harmful.
However, if you define harm as "this is a difficult-to-read, error-prone antipattern that tends to cause bugs and is never truly necessary to resort to", then it's indeed harmful.
There are innumerable questions on Stack Overflow where OP has mixed .then and await and wound up with a bug. I've selected a few for inclusion at the bottom of this post.
As a simple rule of thumb, never combine await and then in a function. At best, it's harder to read than using one or the other, and at worst, it's hiding a bug, usually related to error handling.
Generally, prefer async/await over .then. If you're having a hard time determining when to use which, feel free to go a step further and avoid .then and .catch completely.
That said, I like to occasionally use .then which can be a bit less verbose when error-handling is involved and there's no need to access state on an object that can't be readily passed through the chain:
fetch("https://www.example.com")
  .then(response => {
     if (!response.ok) {
       throw Error(response.statusText);
     }
     return response.json();
   )
  .then(data => console.log(data))
  .catch(err => console.error(err));
Seems cleaner to me than:
(async () => {
  try {
    const response = await fetch("https://www.example.com");
  
    if (!response.ok) {
      throw Error(response.statusText);
    }
    console.log(response.json());
  }
  catch (err) {
    console.error(err);
  }
})();
With top-level await, the bottom code becomes more appealing, although in practice, you're usually writing a function.
An exception I agree with is given by this answer, which is to occasionally use .catch on an await chain to avoid a somewhat ugly try/catch.
Here's an example of when this might be useful:
const fs = require("node:fs/promises");
const exists = async pathName =>
  !!(await fs.stat(pathName).catch(() => false));
May be preferable to the async/await/try/catch version:
const exists = async pathName => {
  try {
    await fs.stat(pathName);
    return true;
  }
  catch (err) {
    return false;
  }
};
...or maybe not depending on if you feel the catch version is too clever.
Note that there is no .then and await mixing here, just .catch rather than try/except. The general heuristic at play here is "flatter is better" (.catch being flatter than try/catch and await being flatter than .then).
(Yes, the example is somewhat contrived, since there's a pretty clean way to use .then/.catch alone for this particular task, but the pattern can appear in other contexts from time to time)
If there's any doubt, stick to the "never mix" rule.
As promised, here's a small selection of examples I've seen of confusion caused by mixing await and then (plus a few other promise antipatterns):
And related threads: