First off, the premise is flawed. You most definitely can modify classes at runtime, e.g. in Ruby:
class Foo; end
foo = Foo.new
foo.bar
# NoMethodError: undefined method `bar' for #<Foo:0xdeadbeef4815162342>
class Foo; def bar; 'Hello' end end
foo.bar
# => 'Hello'
Python:
class Foo: pass
foo = Foo()
foo.bar()
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: Foo instance has no attribute 'bar'
Foo.bar = lambda self: "Hello"
foo.bar()
# => "Hello"
On the other hand, there are prototype-based languages, which do not allow you to modify the prototype at runtime, most notably the statically typed prototype-based languages.
Now, to answer your question:
But it seems to me that needing the ability to add new properties/methods to your classes at runtime would be indicative of the code author not fully anticipating the needs and responsibilities of the class when defining it.
Yes. It’s Difficult to Make Predictions, Especially About the Future. Therefore, it is sometimes hard if not impossible to know what the shape of an object will be until runtime. Think, for example, of an XML deserializer, which creates objects described by an XML document, whose shape is described by an XML Schema, both of which are passed as command line arguments at runtime.
Steve Yegge's classic rant about The Universal Design Pattern is another example, where being able to dynamically add and remove properties from objects is desirable. He gives several case studies, where people have re-invented prototypes and dynamic properties on top of languages that don't have them natively, including inside the Eclipse JDT written in Java and Steve Yegge's own multiplayer role-playing game Wyvern, also written in Java. In Wyvern, property bags with prototypes are being used to model more or less all game objects.