You can check to see what command a keybinding runs with
C-h k runs
describe-key). If you do that
C-x 0, you get the following docstring:
C-x 0 runs the command delete-window (found in global-map), which
is an interactive compiled Lisp function in ‘window.el’.
It is bound to
(delete-window &optional WINDOW)
WINDOW must be a valid window and defaults to the selected one.
If the variable
ignore-window-parameters is non-nil or the
delete-window parameter of WINDOW equals
t, do not process any
parameters of WINDOW. Otherwise, if the
parameter of WINDOW specifies a function, call that function with
WINDOW as its sole argument and return the value returned by that
Otherwise, if WINDOW is part of an atomic window, call
delete-window with the root of the atomic window as its
argument. Signal an error if WINDOW is either the only window on
its frame, the last non-side window, or part of an atomic window
that is its frame’s root window.
delete-window is for deleting windows and NOT frames. The
docstring lets you know why it is signaling the errors you're seeing.
If you want to delete a frame, you need to use the command
delete-frame, which, by default, is bound to
C-x 5 0.
If you really want one command to do it all, below is a simple
option (lightly tested) that deletes a window and, if it's the
last one, deletes the frame it's in:
(defun delete-window-or-frame (&optional window frame force)
(if (= 1 (length (window-list frame)))
(delete-frame frame force)