As far as I can tell, the behavior is as designed/intended.
The error your are getting has its origin in the server, which rejects the "Write" operation. QuickOPC informs you about the problem by throwing the exception. The inner exception says it is a COMException; it does not have a particularly helpful error code or message ("Unspecified error", which corresponds to E_FAIL), but that is because the OPC server decided to return this error code.
The exception (of OpcException type) is unhandled, because your code does not handle it. Throwing the exception is our intent here - you can decide what to do about it (ignore, report to the user, etc.). Note that you may get exceptions for many other reasons as well (server down, ...), so do not think just in terms of exceeding string lengths etc. You can read about the error handling in the documentation. Basically you should wrap calls like WriteItemValue in a try/catch block, and catch OpcException.
I am copying a part of the documentation here, for convenience: It is from Section 13 Best Practices, 13.2:
13.2 With single-operand synchronous methods, only catch OpcException or UAException
Methods that operate on a single element, e.g. an OPC Data Access item, throw an OpcException exception for all OPC-related errors. In OPC-UA, UAException is used for the same purpose. The only other exceptions that can be thrown are program execution-related errors (such as OutOfMemoryException, or StackOverflowException), and argument validation exceptions, such as ArgumentException.
When you catch OpcException or UAException, you are completely safe that all OPC-related situations that you cannot control will be covered. This includes errors related to arguments that can only be discovered in run-time and depend on the state of environment. For example, an invalid OPC-DA item ID does not throw ArgumentException, but still an OpcException. So, even if something changes in the target OPC server, you can handle it by catching OpcException (or UAException). For more information, see ERROR HANDLING.
By catching other exceptions than OpcException (or UAException) in this case, you could hide programming or catastrophic errors that should not be handled in this way.
The SubscribeXXXX and UnsubscribeXXXX methods, such as EasyDAClient.SubscribeItem, EasyDAClient.UnsubscribeItem, or EasyAEClient.SubscribeEvents, work asynchronously. This rule therefore does not apply to them; instead, see DO NOT CATCH ANY EXCEPTIONS WITH ASYNCHRONOUS OR MULTIPLE-OPERAND METHODS.
---
In theory the error may also come from some other call (not directly from the target OPC Server), but that's unlikely. If you want to verify this, just use e.g. the Softing demo client, execute the same test, and observe the errors in the Errors tab.
I hope this helps
Best regards