Designing a good API is an art form, unfortunately. I've seen some efforts to graduate this process to science or engineering level, but nothing even close to accepted by a majority or programmers so far.
One particular problem I face from time to time is related to helpful APIs. Those tend to help the programmer complete its task by adding common fallback processing paths. It usually goes something like this: the API designer convinces himself that X this is the most common operation, so when user doesn't do it, we do it for them. The programmers have less to write because the API will do the right thingâ¢.
My problem with those APIs is that they tend to fail silently. The program keeps on going, using the default processing path, and eventually the programmer lack of decision will bite him with an exception or a core dump (pick your poison).
I tend to prefer non-helpful APIs: if the programmer should make a decision, force him to do so and die as soon as possible if he doesn't, compile time if you have that concept and if you can make it happen then.
The decision the programmer needs to make could even be to do the default processing path, but he must make one.
It is a little bit more code to write, but it pays of enormously in long-term readability by eliminating the hidden default behavior. Every action is explicit, so a new programmer looking at the code (eg. you, the same one who wrote it the first time, only 6 months later) will need less background information to understand it.
So help you API users. Die often, die early, be explicit and stop helping lazy programmers.