| name | hti-fallback-guard |
| description | In this repo, avoid sloppy fallback logic. Prefer explicit failures, narrow error handling, and clearly marked TODOs over fake success paths. |
HTI Fallback & Failure Handling
This Skill defines how to handle errors and "fallback" behavior in the hti-zen-harness project.
Core Principles
When working in this repo:
No fake success.
- Do not hide failures behind:
- Silent
except Exception: pass - Returning empty objects (
{},[]) or dummy values as if things worked - Swallowing errors and logging nothing
- Silent
- If something really cannot be implemented yet, mark it explicitly as such.
- Do not hide failures behind:
Prefer explicit failure over magical fallback.
- It is better to:
- Raise a clear, specific exception, or
- Return an explicit error result /
Result-style object
- ...than to pretend everything is fine.
- It is better to:
Be narrow and honest with error handling.
- Catch specific exceptions (e.g.,
requests.Timeout,ValueError), not blanketException, unless there is a very strong reason. - When catching an exception, do at least one of:
- Log it with clear context, OR
- Re-raise it, OR
- Convert it into a clearly named error type / return value.
- Catch specific exceptions (e.g.,
No "mystery fallback" branches.
- Avoid patterns like:
def get_config(): try: return load_from_disk() except Exception: return {} - Instead, make the failure visible:
def get_config(): try: return load_from_disk() except FileNotFoundError as e: raise ConfigMissingError("Config file not found") from e
- Avoid patterns like:
Approved Alternatives to Bad Fallbacks
When you feel tempted to add "just in case" fallback logic, use one of these patterns instead:
1. Explicit TODO with loud marker
If something truly can't be implemented yet:
def fetch_remote_status():
# HTI-TODO: Implement real remote status fetching.
raise NotImplementedError("fetch_remote_status is not yet implemented for HTI harness")
Guidelines:
- Use
HTI-TODOin comments to make search/refactoring easier. - Do not silently return a fake value.
2. Logged error + re-raise
When you want extra context but don't want to hide the failure:
def run_harness_step():
try:
return do_step()
except HarnessStepError as e:
logger.error("Harness step failed: %s", e)
raise
3. Structured, explicit error result
If the calling code already uses structured results:
@dataclass
class StepResult:
ok: bool
error: str | None = None
data: dict[str, Any] | None = None
def run_harness_step() -> StepResult:
try:
data = do_step()
return StepResult(ok=True, data=data)
except HarnessStepError as e:
return StepResult(ok=False, error=f"harness step failed: {e}")
Rules:
- Never set
ok=Truewhen something actually failed. - Call sites should check
okand handle errors explicitly.
When You Think You "Need" a Fallback
Before adding fallback code, follow this checklist:
Ask: what is the correct behavior if this fails?
- Crash fast and loudly?
- Retry?
- Skip this step but continue others?
If there is genuine choice, do one of:
- Briefly outline 2–3 options in your response and pick the safest one by default.
- Only ask the user when the choice meaningfully affects behavior or safety.
Document the behavior.
- If you add a fallback, document:
- When it triggers
- What it does
- Why this is acceptable in HTI/Zen context
- If you add a fallback, document:
Example:
def run_analysis():
"""
Run analysis for the HTI Zen harness.
Failure behavior:
- If the upstream model call fails, we raise a clear error.
- We do NOT silently fallback to dummy data.
"""
...
Patterns to Avoid in This Repo
Claude should avoid generating code like:
# BAD: silent swallowing
try:
result = call_model(prompt)
except Exception:
result = {"status": "ok"} # Pretend success
# BAD: vague TODO fallback in production path
if not result:
# TODO: handle better
return {}
Or:
# BAD: doing something random "just to return something"
def pick_model():
try:
return pick_best_model()
except Exception:
return "gpt-5" # arbitrary default with no explanation
Interaction with Testing
When writing or updating tests in this repo:
- Prefer tests that prove we're not silently falling back.
Example patterns:
- Assert that an invalid config raises a specific error.
- Assert that missing dependencies cause clear failures, not silent no-ops.
- If a fallback exists, add a test that triggers it and confirms:
- It's documented
- It's safe
- It's clearly distinguishable from the normal path.
How to Use This Skill
Claude:
When editing code in hti-zen-harness, load and follow these guidelines whenever:
- You add error handling
- You touch network / API / MCP calls
- You consider "best-effort" or "fallback" behavior
If a user asks you to "just make it work even if X fails,":
- Explain briefly what trade-off you're making
- Choose explicit, debuggable behavior over silent fallbacks
- Use
HTI-TODOmarkers when something is intentionally left incomplete