Skip to main content

Safety, Refusals & Fallbacks

Intermediate

In production, your code must handle the case where Claude won't (or can't) answer as expected. Done well, this is invisible to users; done badly, it's a crash or a confusing reply.

What you'll learn
  • Tell a model refusal apart from a classifier/safety block — and why it matters
  • Handle a refusal as a normal outcome instead of crashing or showing an empty reply
  • Cut the refusals you didn't want, without trying to jailbreak the ones you did
  • Pick a fallback: clarifying question, safe alternative, or human handoff

Two different things

  • A model refusal — Claude declines a request (e.g. it judges it harmful). The response signals this (commonly via a refusal stop_reason/content). Treat it as a normal outcome, not an error.
  • A classifier/safety block — a separate safety layer may block content. This can look different from a model refusal.

Knowing which you got lets you respond appropriately rather than retrying blindly.

Handle it gracefully

resp = client.messages.create(...)
if getattr(resp, "stop_reason", None) == "refusal":
# Don't show a raw/empty result. Offer a safe fallback or a clarifying ask.
show_user("I can't help with that as asked. Here's what I can do instead…")
else:
render(resp)

Reduce unwanted refusals

  • Add legitimate context. A request can pattern-match to something sensitive when intent is benign; stating the real, legitimate purpose helps.
  • Be specific. Vague or edgy phrasing invites caution.
  • Don't fight it. If a request is genuinely disallowed, refusal is correct — design a graceful path, don't try to jailbreak.

Add the legitimate context up front

I am a security engineer at [company] reviewing our own authentication code
before a release. Below is a function we wrote and own.

Identify weaknesses in it and explain how an attacker would exploit each one,
so we can fix them before we ship.

[code]

Fallback patterns

  • A clarifying question instead of a dead end.
  • A safe alternative ("I can summarize the public info instead").
  • For pipelines, route to a human when confidence/eligibility is low.
Guided walkthrough1 of 4
  1. Inspect the response for a refusal signal before you render it. Never pipe an unchecked response straight into your UI — that is how users get a blank box or a raw object.

Check yourself

0/3
  1. Your code gets a refusal back from Claude. What's the right way to treat it?
  2. A benign request keeps getting refused. What's the first thing to try?
  3. Why does it matter whether you got a model refusal or a classifier/safety block?
Key takeaways
  • A refusal is an outcome, not an error — detect it before rendering, always.
  • Model refusal and classifier block are different things; identify which you got.
  • Unwanted refusals usually shrink when you add legitimate context and get specific.
  • If a request is genuinely disallowed, refusal is correct — build a graceful path, don't jailbreak.
  • Fallbacks in order: clarifying question, safe alternative, human handoff.

Next