refactored to remove panics, return errors, and fewer type assertions