some quick thoughts on your post.
you are thinking too much in the mode of C/C++:
if you want to signal that you have searched and not found an object you could return a pointer to the NULL *object*, for example (as in python, None). what good is that? well accidently using it may still be an error, but not one that will go unnoticed as can happen so often in C (with invalid references, not NULL ones, but the point would be that you couldn't have a pointer that is invalid here.)
as far as not having cyclic references, it would be enforced statically (at compile time). ie no expression where you create two strong pointers from one would be allowed. (not in C where you can turn a pointer into an int or have pointer aliasing).
doing garbage collection and handling scripting languages, you'd make the memory manager/allocator hold the strong reference i would guess.
i'm not saying that any of these are good suggestions, or that the ideas are good (though they are interesting); i'm just pointing out how you might do them.