Guides / Developers

How to write a SKILL.md that still works when a tool is missing

Three fallback patterns for agent skills, with verbatim examples from free skills, and the study numbers on how rare fallbacks are.

A skill that says "use WebFetch" works in one tool and quietly fails in the others. The assistant reads the instruction, finds no such tool, and either invents a way around it or stops with no explanation. The fix is cheap: say what you need, then say what to do without it.

How rare fallbacks are

In our portability study we ran a regular-expression test over 69 of the most-installed skills on skills.sh. Only 17 of 69 contain any fallback phrase, such as "if you cannot..." or "ask the user to paste". Of the 29 skills with some tie to one agent product, 23 have none. Of the 14 skills that bundle a script, 4 also have a fallback phrase. The test sees phrases, not meaning, so a phrase does not prove the fallback works. But the pattern is clear enough: most skills assume their tools exist.

Pattern 1: name the capability, then give the manual route

The first habit is to describe what you need, not the product feature that provides it.

A typical before, written by us to illustrate the problem (it is not quoted from any one skill):

Use WebFetch to read the pages.

And an after, quoted verbatim from search-intent-page-brief in our free repo:

Fetch them with whatever web tool you have. If you cannot fetch, ask the user to paste each page's title, headings and any lists or tables.

The after names no vendor tool. It also says exactly what to ask for, so the user knows what to paste.

Pattern 2: say what to do when the tool fails, not only when it is absent

A tool can be present and still fail: a network error, a blocked page, a missing fact. The skill should say what each failure means.

A typical before, again our illustration:

Run the script and use its output.

And an after, quoted verbatim from agent-ready-quick-check:

If the script returns an error or leaves a fact out, say "not found by the script" and use a placeholder or ask the user to paste it. Never write a fetcher to get round it.

Two things matter here. The skill gives a phrase to use ("not found by the script"), so the output tells the reader a gap exists. And it rules out the tempting workaround. Without the last sentence, many assistants will write their own fetcher, which is exactly what you were trying to control.

Pattern 3: when you cannot do the job honestly, degrade and say so

Sometimes a fallback cannot match the main route. The honest version does a smaller job and states what it did not do.

A typical before:

View each image and write alt text.

And an after, quoted verbatim from shopify-alt-text-writer:

If you can't view images, write from metadata (title, variant, view_hint, filename, position) and say in the summary that the text wasn't checked against the photos.

The skill does not pretend. It switches to the data it has and puts the limit in the output where the reader will see it.

The same skill has the sharpest version of a related rule: "If you can't run code, or a shell command is denied or fails: switch to this path straight away. Don't stop to ask for permission." A fallback that waits for permission is only half a fallback.

When stopping is the right fallback

Some jobs should not be done by hand. agent-ready-quick-check says: "No shell at all? Say you can't run the check and stop." A score computed by a script is worth giving only if a script computed it. Stopping with a clear message beats a made-up number.

A checklist you can apply today

  1. List every tool, file, network call and script your skill relies on.
  2. For each, write one line: "If this is missing, do X." X is one of: ask the user to paste, use a smaller route and say so, or stop and say why.
  3. Write the stop condition first. Before you write a fallback, write what clears it: the evidence that the missing tool or data is back, or that the user's pasted text is enough. Otherwise a fallback becomes the permanent route. (Suggested by an agent on Moltbook.) Add a "resume when:" line next to each stop: say which condition lets the skill continue, for example "resume when: the user pastes the page text, or the tool is back". (Also suggested by an agent on Moltbook.)
  4. Describe tools by capability ("a web tool", "a shell") and not by product name.
  5. Give the exact words to use when a gap shows up, so the gap reaches the output.
  6. Forbid the workaround you do not want. Assistants fill silence with improvisation.
  7. Put a plain-prompt version next to the skill for chat apps that cannot load skills at all. Each of our skills ships a prompt.md for this.
  8. Test it in a session where the tool is missing. Turn the tool off, run the skill, and read what it does.

Limits

  • Fallback phrases are a measurable proxy, not proof. A fallback can be present and badly written.
  • We tested our own skills on one family of models, so we cannot say how every assistant reacts to these lines. Read what yours does.
  • A fallback adds length. Keep it to a line or two, and keep SKILL.md short.
  • The three "before" lines are our illustrations of a common pattern. They are not quotes from any skill in the study.

We make agent skills. The free ones quoted here are at proskillpacks/skills and the study data is at the portability study.

Browse all skills in the catalog