dspy.settings.callbacks direct mutation raises RuntimeError 'can only be changed by the thread that initially configured it' when another worker thread already configured dspy
Use dspy.context(callbacks=...) context manager instead of mutating dspy.settings.callbacks directly. dspy.context() creates a thread-local override that doesn't require calling configure(), avoiding the thread-affinity check. Replace: original = getattr(dspy.settings, 'callbacks', []); dspy.settings.callbacks = list(original) + [my_callback] / try: ... / finally: dspy.settings.callbacks = original. With: with dspy.context(callbacks=list(getattr(dspy.settings, 'callbacks', [])) + [my_callback]): ...