Turns out the ID needs to be a valid ObjectId, e.g. 24 characters and no illegal tokens.
- If the ID is valid but does not reference an existing document then I get a 404 as expected.
- If the ID format is invalid (e.g. only 12 characters or contains illegal tokens like '@') then I get an Exception.
When I compare behaviour with an equivalent Node.js + Mongoose app results are very similar.
For example if deliberately querying with a malformed 12 character ID I get this stacktrace in Node:
{ message: 'Cast to ObjectId failed for value "51bded70543f" at path "_id"',
name: 'CastError',
type: 'ObjectId',
value: '51bded70543f',
path: '_id' }
Not sure if this exception is the underlying error in the Play app too but it gave enough of a clue. The answer would seem to be pre-validate IDs before calling find(query).one[T].