Most workflow builders crash or send a message with the blank left in place. GuestMaker gives hotels three explicit choices, and skip is the default for a reason.

Every hotel journey builder promises personalization: pull the guest's first name, drop in their reservation date, reference the room type they booked. The demo always works because the demo data is complete. The moment you run it against your real contact list, a guest is missing a first name, or a reservation field is blank because it came from a booking source that doesn't populate it, and the question stops being theoretical. What does the send actually do?
Most builders only have one answer, and it's usually implicit rather than chosen. Some crash the entire workflow execution the moment a template variable resolves to nothing. Others send the message anyway, blank left in place, so a guest opens an email that greets them with "Hi ," the personalization field left empty exactly where a name should have gone. Neither is a decision the hotel made. It's just what the code happens to do when it hits an empty string.
GuestMaker's journey builder treats this as a real configuration choice, because it is one. When a personalization variable is missing at send time, there are three explicit failure modes, and a hotel picks which one applies: skip_contact, the recommended default, where this one guest is skipped and everyone else in the journey continues normally; fail_execution, where the entire journey execution stops for that specific guest; and send_anyway, where the message goes out with the blank left exactly where the variable would have been. Three different outcomes for the identical missing-data event, and the hotel decides which one fits the campaign.
The recommended default is skip_contact, and the reasoning behind that default is simple. A skip means one guest, out of however many are in that journey step, doesn't get this particular send. Nothing else changes: everyone else in the journey continues running normally. It's the option that assumes the safest thing to do with incomplete data is nothing, rather than something wrong.
Send_anyway exists because there are real cases where a blank is better than a skip, or at least not worse. A generic "Your stay is coming up" reminder with a missing room type might still be useful even without that detail filled in. But it has to be a deliberate choice, made by someone who looked at the template and decided a blank field wouldn't embarrass the brand, not a default nobody actively selected. The difference that matters is between a hotel choosing this and a builder defaulting to it. One is a decision made once, in the node's settings, with the actual template in front of you. The other is a surprise a guest finds in their inbox.
Fail_execution is the strictest option, and it exists for the campaigns where a partial send is actively worse than no send. Think of a confirmation flow that depends on a specific reservation field being present to be coherent at all. If that field is missing, you don't want a version of the message going out with a hole in it, and you don't want the rest of that guest's journey to quietly assume the step succeeded. Stopping the whole execution for that guest is the correct failure, even though it's the most disruptive one.
There's a second, quieter place where "skip" shows up in a GuestMaker journey, and it's easy to assume it behaves like the first one. It doesn't, and the difference matters more than it looks.
Frequency capping on an email node, called Smart Sending, exists to stop a guest from being hit with too many messages in too short a window. The instinctive assumption is that a capped send gets postponed, held until the guest is eligible again, then sent late. That's not what happens. A frequency-capped send is skipped outright. It doesn't queue, it doesn't wait for a clear window, it doesn't fire later in the day once the cap resets. It just doesn't go out, and that decision is tracked with its own explicit reason, kept separate from anything that's a genuine wait or delay node in the journey.
That distinction is only useful if you can actually see it. When a hotel's marketing team looks at a journey execution and a step didn't fire, the honest question is always "is this guest still waiting, or did we decide not to send to them at all?" Those are different problems with different fixes. A guest stuck in a delay node might need the wait condition checked. A guest whose send was skipped for frequency reasons was never going to receive it on that run, full stop, and the record says so plainly instead of leaving the two indistinguishable in an execution log.
What "skip, not delay" actually buys a hotel is easy to undersell as a minor implementation detail. It isn't. A delay implies the send is still coming, just later, which means anyone reading the journey's execution history would reasonably expect to find it eventually, sent a few hours or days after the cap cleared. A skip makes no such promise. It says: for this run, on this trigger, this guest did not receive this message, and that decision is final for this step.
The result is a more honest account of what actually happened, and it avoids a worse failure mode: a message arriving unexpectedly late, disconnected from whatever originally triggered it, because a delayed-send design tried to catch up on a backlog. A guest getting a "your check-in is tomorrow" reminder two days after check-in, because it was queued behind a frequency cap rather than skipped, is a worse outcome than never getting that particular send at all. Nobody sets out to build that behavior. It's what happens when "skip" and "delay" get conflated under one mechanism instead of being kept as two separate, clearly labeled outcomes.
We won't put a number here for how often a cap actually triggers on a given send, because it depends entirely on how a hotel has configured its own frequency rules, how many journeys are live, and how often a guest crosses paths with more than one of them. What's true regardless of the number is that the mechanism has to be a skip, tracked as a skip, or the hotel loses the ability to tell "still coming" from "didn't happen" when they go looking.
Missing personalization fields and frequency caps aren't edge cases in the sense of being rare. They're edge cases in the sense of being the exact moment a workflow builder's design choices stop being invisible. Most days, every guest has a first name on file and nobody's anywhere near a frequency cap, so it genuinely doesn't matter what the builder would do if that weren't true. The design only gets tested the day it isn't true, and by then the message has already gone out, or already failed to.
There's a third place this same instinct shows up, on the consent side rather than the data side. Marketing-category template sends check, before sending, whether a contact is actually allowed to receive that category of message. It's a gate meant to hold every time. But what happens when the check itself fails to run correctly, an internal error rather than a genuine "no" answer? GuestMaker's answer is deliberately fail-open. If the consent check can't be evaluated, the send is allowed to proceed rather than being silently blocked, a deliberate tradeoff that favors availability over silence. A genuine "no" still blocks the send; it's specifically an internal failure to evaluate the check that doesn't turn into a mass, invisible suppression of real, wanted sends. It's the same underlying principle as skip_contact and Smart Sending: name the failure mode on purpose, rather than let an edge case decide it by accident.
None of this is really about missing fields, or frequency caps, or consent checks individually. It's about whether a hotel journey builder treats the moment your data isn't perfect as a scenario worth designing for, or as something that only gets handled by whatever the code happens to fall into. Real contact databases have gaps. A reservation field from one booking source doesn't match a field from another. A guest's name genuinely isn't in the system yet. None of that is a data quality failure so much as it's just what a real hotel's contact list looks like on a Tuesday.
A journey builder that only has one answer for all of that, crash the run or send it broken, isn't simpler. It's just deciding for you, silently, and hoping you never notice which choice it made. Skip_contact, fail_execution, and send_anyway exist because the right answer genuinely depends on the campaign. A confirmation flow and a generic newsletter reminder don't deserve the same failure mode, and pretending they do is how a hotel ends up apologizing for a blank in a guest's inbox instead of having decided, in advance, that the send should never have gone out that way.
Twenty minutes, your real properties, no generic demo environment.