I'm sending a "general" response because I'm in a bit of a hurry. I had a similar problem but I might not have been getting a "fatal error". Just a heads up, you might only need to read the last sentence of this reply.
What I did to solve it: Instead of running a custom function from within the action_tile itself, I would 'setq' a flag that would later get passed to my routine, long after the dialog box did its thing and was unloaded. This advice more applies to the first bit of code you posted. We're limited to what can actually be placed in the action_tile expression but there are work-arounds, such as setting a flag of some sort (you might be doing this in your second snippet of code).
For the second bit of code you posted, I notice you aren't including "done_dialog" in your action_tile. And then you run your custom function before the dialog is unloaded. This will cause unpredictable results.
I would do something like this:
(action_tile "your_key" "(done_dialog) (setq myFlag \"some_value\")")
(start_dialog)
(unload_dialog "your_dialog_symbol")
(if (= myFlag "some_value") *****or use 'cond'
(xfunction........
As-is, you might get away with simply placing your 'xfunction' after unloading the dialog box.