Documenting how callers should deal with this seems out of scope, would just describe behaviour. Let's also use more complete Doxygen syntax while we're at it.
<details>
<summary>git diff on 76359bee61</summary>
diff --git a/src/kernel/bitcoinkernel.h b/src/kernel/bitcoinkernel.h
index ba6daf72fd..0ada5576a9 100644
--- a/src/kernel/bitcoinkernel.h
+++ b/src/kernel/bitcoinkernel.h
@@ -391,11 +391,11 @@ typedef void (*btck_ValidationInterfaceBlockDisconnected)(void* user_data, btck_
/**
* Function signature for serializing data.
*
- * The bytes pointer may be null when size is zero. Callers that construct a
- * language-level slice or array view from the arguments must handle that
- * case, as some languages require a non-null pointer even for an empty view.
- *
- * Returns 0 to indicate success.
+ * [@param](/bitcoin-bitcoin/contributor/param/)[in] bytes The data to write. Can be null if size is 0.
+ * [@param](/bitcoin-bitcoin/contributor/param/)[in] size The number of bytes in the data.
+ * [@param](/bitcoin-bitcoin/contributor/param/)[in] userdata Holds the user-defined opaque structure that was given
+ * with the writer.
+ * [@return](/bitcoin-bitcoin/contributor/return/) 0 on success.
*/
typedef int (*btck_WriteBytes)(const void* bytes, size_t size, void* userdata);
</details>