Mole Bug Patterns
tw93/Mole
A catalog of recurring bug shapes in the Mole Mac cleaner, used to review safety-sensitive diffs for deletion safety, unbounded commands, shell traps and weak tests.
统一错误处理系统。在添加 API 端点、修改错误处理、添加前端 API 调用、编写错误相关测试时使用. An agent skill from microsoft/data-formulator.
$ npx skills add microsoft/data-formulator --skill error-handling -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install microsoft/data-formulator error-handling --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/microsoft/data-formulator.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.cursor/skills/error-handling .claude/skills/error-handling && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "error-handling" agent skill from https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handling into .claude/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handlingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add microsoft/data-formulator --skill error-handling -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install microsoft/data-formulator error-handling --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/data-formulator.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.cursor/skills/error-handling .agents/skills/error-handling && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "error-handling" agent skill from https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handling into .agents/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add microsoft/data-formulator --skill error-handling -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install microsoft/data-formulator error-handling --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/data-formulator.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.cursor/skills/error-handling .cursor/skills/error-handling && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "error-handling" agent skill from https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handling into .cursor/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/microsoft/data-formulator.git --path .cursor/skills/error-handling--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add microsoft/data-formulator --skill error-handling -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install microsoft/data-formulator error-handling --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/data-formulator.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.cursor/skills/error-handling .gemini/skills/error-handling && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "error-handling" agent skill from https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handling into .gemini/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install microsoft/data-formulator error-handlingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add microsoft/data-formulator --skill error-handling -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/microsoft/data-formulator.git skills-src && mkdir -p .github/skills && cp -r skills-src/.cursor/skills/error-handling .github/skills/error-handling && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "error-handling" agent skill from https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handling into .github/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add microsoft/data-formulator --skill error-handling -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install microsoft/data-formulator error-handling --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/data-formulator.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.cursor/skills/error-handling .opencode/skills/error-handling && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "error-handling" agent skill from https://github.com/microsoft/data-formulator/tree/main/.cursor/skills/error-handling into .opencode/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
error-handling统一错误处理系统。在添加 API 端点、修改错误处理、添加前端 API 调用、编写错误相关测试时使用. An agent skill from microsoft/data-formulator.
Error Handling is an agent skill from microsoft/data-formulator, published by the product's own GitHub organization. 统一错误处理系统。在添加 API 端点、修改错误处理、添加前端 API 调用、编写错误相关测试时使用。
Its SKILL.md is about 3.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Error handling. The repository describes itself as: 🪄 Data Formulator is an interactive AI-powered data analysis system makes it easy to connect, explore and visualize data. The licence is MIT.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 5477f0e. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python and typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Error Handling loads about 3.8k tokens when it runs. Until then it costs about 17 tokens; SKILL.md has 1,094 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from microsoft/data-formulator at commit 5477f0e, republished under its MIT licence (© microsoft). 1,094 words, ~3,789 tokens.
.claude/skills/error-handling/SKILL.md (or your agent's skills folder).Unified error handling system for DF. Use when adding API endpoints, modifying error handling, or adding frontend API calls.
Prerequisites: Read
docs/dev-guides/7-unified-error-handling.mdbefore changing API error behavior. Readdocs/dev-guides/2-log-sanitization.mdwhen the work involves logging, credentials, external services, or DataLoaders. If your work introduces new error handling patterns or conventions, update this file and related dev-guides accordingly.
Frontend Backend
──────── ───────
apiClient.ts errors.py
├── apiRequest() ←── JSON ──── ├── ErrorCode (enum)
├── streamRequest() ←── NDJSON ── └── AppError (exception)
└── parseStreamLine()
error_handler.py
errorCodes.ts ├── register_error_handlers(app)
└── getErrorMessage() ├── classify_and_wrap_llm_error()
└── stream_error_event()
errorHandler.ts
└── handleApiError() security/sanitize.py
└── classify_llm_error() (internal)
MessageSnackbar ← dfSlice.messagesUse this contract for all new or reworked DF APIs:
| Scenario | HTTP | Shape |
|---|---|---|
| Non-streaming success | 200 | {"status": "success", "data": ...} |
| Non-streaming business/validation error | 200 | {"status": "error", "error": {"code", "message", "retry", "request_id"}} |
| Non-streaming auth/authorization error | 401 / 403 | same structured error body |
| Streaming preflight error | 200 | application/json + {"status": "error", "error": ...} |
| Streaming in-flight fatal error | 200 | NDJSON line: {"type": "error", "error": ...} |
| No Flask route / too large / unhandled crash | 404 / 413 / 500 | transport-level error |
Do not use HTTP 400/422 for application validation errors in new code.
Do not convert in-flight NDJSON errors to status: "error"; once the stream has
started, event type is the protocol discriminator.
Application-controlled business and validation errors return HTTP 200 with
status: "error" in the body. Only these use non-200:
401/403 — auth errors (AUTH_REQUIRED, AUTH_EXPIRED, ACCESS_DENIED)404 — no matching Flask route413 — WSGI body limit exceeded500 — unhandled exception (program bug)from data_formulator.errors import AppError, ErrorCode
from data_formulator.error_handler import json_ok
@bp.route('/my-endpoint', methods=['POST'])
def my_endpoint():
content = request.get_json()
if not content.get('required_field'):
raise AppError(ErrorCode.INVALID_REQUEST, "Missing required_field")
try:
result = do_work(content)
except SomeBusinessError as e:
raise AppError(ErrorCode.DATA_LOAD_ERROR, "Failed to load data") from e
except Exception as e:
from data_formulator.error_handler import classify_and_wrap_llm_error
raise classify_and_wrap_llm_error(e) from e
return json_ok(result)
# Global handler returns: HTTP 200 + {"status": "error", "error": {code, message, retry}}
# Auth errors (AUTH_REQUIRED/AUTH_EXPIRED/ACCESS_DENIED) return 401/403Legacy {"status": "error", "message": "..."}, error_message, bare {error},
and status: "ok" responses are historical formats. Do not add new compatibility
branches for them; migrate the route to json_ok() / AppError before using
apiRequest().
Validation MUST be outside the generator. Failures return 200 JSON (not NDJSON).
from data_formulator.errors import AppError, ErrorCode
from data_formulator.error_handler import (
classify_and_wrap_llm_error,
stream_error_event,
stream_preflight_error,
)
@bp.route('/my-stream', methods=['POST'])
def my_stream():
if not request.is_json:
return stream_preflight_error(
AppError(ErrorCode.INVALID_REQUEST, "Invalid request")
)
content = request.get_json()
client = get_client(content['model'])
def generate():
try:
for event in agent.run(...):
yield json.dumps(event, ensure_ascii=False) + "\n"
except Exception as e:
yield stream_error_event(classify_and_wrap_llm_error(e))
return Response(stream_with_context(generate()), mimetype='application/x-ndjson')Streaming runtime errors intentionally use {"type": "error", "error": ...}.
They cannot use a top-level status envelope because the HTTP response and NDJSON
event stream have already started.
import { apiRequest } from '../app/apiClient';
import { handleApiError } from '../app/errorHandler';
try {
const { data } = await apiRequest<ResponseType>(getUrls().MY_ENDPOINT, {
method: 'POST',
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' },
});
} catch (e) {
handleApiError(e, 'MyComponent');
}For UI loading state, model the request lifecycle explicitly with
LoadableState from src/app/loadableState.ts. Do not infer loading from
missing data (!data), because failed requests may legitimately leave data
empty while loading has ended.
import { streamRequest } from '../app/apiClient';
import { handleApiError } from '../app/errorHandler';
try {
for await (const event of streamRequest(url, options, abortController.signal)) {
switch (event.type) {
case 'text_delta':
break;
case 'error':
// Error arrived mid-stream — show inline in component.
break;
case 'done':
break;
}
}
} catch (e) {
handleApiError(e, 'MyComponent');
}handleApiError(e, 'MyComponent', {
onAuth: () => redirectToLogin(), // AUTH_REQUIRED / AUTH_EXPIRED
onRetryable: () => retryOperation(), // LLM_RATE_LIMIT / LLM_TIMEOUT
silent: true, // don't show Snackbar (component handles display)
});DF API consumers should use apiRequest() / streamRequest() and
handleApiError(). Direct fetchWithIdentity() is for lower-level client helpers
and explicit protocol exceptions such as file downloads, blob/CSV responses,
OIDC redirects, SPA fallback, or third-party URLs.
Do not apply the normal JSON API protocol mechanically to file downloads / CSV
streaming, SPA fallback, OIDC redirect flows, frontend fetches to third-party
URLs, or errors after a streaming response has already started. Check the route's
protocol first, then preserve safe error bodies and avoid str(exc) exposure.
Backend — Add to py-src/data_formulator/errors.py ErrorCode:
MY_NEW_ERROR = "MY_NEW_ERROR"No HTTP mapping needed — defaults to HTTP 200. Only add to ERROR_CODE_HTTP_STATUS if it's an auth code.
Frontend mapping — Add to src/app/errorCodes.ts ERROR_CODE_I18N_MAP:
MY_NEW_ERROR: 'errors.myNewError',Translations — Add to both locale files:
src/i18n/locales/en/errors.json: "myNewError": "English message"src/i18n/locales/zh/errors.json: "myNewError": "中文消息"All streaming endpoints are now on the unified protocol:
| Endpoint | Format | Notes |
|---|---|---|
/data-agent-streaming | NDJSON + stream_error_event() | Emits top-level type events; errors use {type:"error", error:{...}} |
/get-recommendation-questions | NDJSON + stream_error_event() | Was error: {json} prefix |
/generate-report-chat | Pure NDJSON + stream_error_event() | Was SSE data: {json} prefix |
/data-loading-chat | NDJSON + stream_error_event() | str(e) removed |
/clean-data-stream | NDJSON + stream_error_event() | Was \n{json}\n format |
Non-streaming endpoints:
| Endpoint | Error Format | Notes |
|---|---|---|
/chart-insight | AppError → HTTP 200 + {status:"error", error:{code,message,retry}} | Fully migrated. Frontend uses fetchChartInsight rejected reducer. |
| All migrated endpoints | AppError → HTTP 200 + unified error body | credentials, knowledge, sessions, tables, agents |
/derive-data, /refine-data, /sort-data, /process-data-on-load, /test-model | json_ok() / AppError | Migrated to new format |
Not all .catch(() => {}) are bugs. Use this decision tree:
addMessages or handleApiError().rejected handler with addMessagesif (action.error?.name !== 'AbortError')When consuming a migrated streaming endpoint, handle the current NDJSON event format directly:
const data = JSON.parse(line);
if (data.type === 'error') {
const errMsg = data.error?.message || 'Unknown error';
// show to user...
}For table CRUD endpoints, use the specialized classifier:
from data_formulator.routes.tables import classify_and_raise_db_error
@tables_bp.route('/my-table-op', methods=['POST'])
def my_table_op():
try:
result = workspace.do_something()
return jsonify({"status": "success", "data": result})
except Exception as e:
classify_and_raise_db_error(e)classify_and_raise_db_error maps common DB errors to appropriate AppError codes
(returned as HTTP 200 by the global handler, except ACCESS_DENIED → 403):
TABLE_NOT_FOUND (HTTP 200)INVALID_REQUEST (HTTP 200)ACCESS_DENIED (HTTP 403)CONNECTOR_ERROR (HTTP 200)For connector endpoints, use:
from data_formulator.data_connector import classify_and_raise_connector_error
except Exception as e:
classify_and_raise_connector_error(e, operation="preview")Connector/DataLoader classification is intentionally simple and lives in
data_formulator.data_loader.connector_errors. It maps common failures to a
small stable set: INVALID_REQUEST, CONNECTOR_AUTH_FAILED, AUTH_EXPIRED,
ACCESS_DENIED, DB_CONNECTION_FAILED, DB_QUERY_ERROR, DATA_LOAD_ERROR,
or CONNECTOR_ERROR. Do not add endpoint-local string matching unless the
classifier cannot reasonably cover the category.
All JSON errors include error.request_id and an X-Request-Id response
header. Show/copy this ID for users when reporting backend failures; do not
show raw exception text in production. Unhandled 500 responses must never
include raw tracebacks, even in debug mode; return a safe category plus
request_id and keep full stack traces in server logs only.
When an error isn't reaching the frontend:
{"status": "error", "error": {"code": ..., "message": ...}}{"type": "error", "error": {"code": ..., "message": ...}}application/x-ndjson, not application/json or text/event-streamdata.type === 'error'?register_error_handlers(app) is called in app.pyerrorhandler(Exception) takes priority over global handlersLegacy message / error_message bodies are protocol violations on migrated API paths.
Server-side logs must never leak passwords, tokens, API keys, or connection strings. The project uses a defense-in-depth approach with two layers.
from data_formulator.security.log_sanitizer import (
sanitize_url, sanitize_params, redact_token,
)
# Dict with credentials → sanitize_params()
log.info("Connecting with: %s", sanitize_params(params))
# URL that may embed credentials → sanitize_url()
logger.info("Issuer: %s", sanitize_url(issuer_url))
# Token/API key → redact_token()
logger.debug("Token: %s", redact_token(token))Registered in app.py:configure_logging(). Automatically redacts:
://user:pass@host)Bearer tokenspassword=xxx, api_key=xxx, secret=xxx patternsDisable with LOG_SANITIZE=false for local debugging only.
| Data | Utility | Why not just filter? |
|---|---|---|
dict with password keys | sanitize_params() | Filter can't identify arbitrary password values in dict repr |
| URL from config/env | sanitize_url() | Explicit is clearer; filter is backup |
| Token/key value | redact_token() | Explicit is clearer; filter is backup |
| Normal text | Nothing | Filter handles edge cases |
When adding a module that handles credentials or external services:
logger.*() calls for credential/URL/token loggingsanitize_params() for dicts, sanitize_url() for URLs, redact_token() for tokenstype(exc).__name__ over str(exc) in warning-level logsSENSITIVE_KEYS in log_sanitizer.py| File | Purpose |
|---|---|
py-src/data_formulator/errors.py | ErrorCode enum + AppError exception |
py-src/data_formulator/error_handler.py | Global handlers, classify_and_wrap_llm_error, stream_error_event |
py-src/data_formulator/security/log_sanitizer.py | sanitize_url, sanitize_params, redact_token, SensitiveDataFilter |
py-src/data_formulator/routes/tables.py | classify_and_raise_db_error (database/workspace errors) |
py-src/data_formulator/data_connector.py | classify_and_raise_connector_error (connector errors) |
py-src/data_formulator/security/sanitize.py | classify_llm_error (internal), sanitize_error_message |
src/app/apiClient.ts | apiRequest, streamRequest, parseStreamLine, ApiRequestError |
src/app/errorHandler.ts | handleApiError |
src/app/errorCodes.ts | ERROR_CODE_I18N_MAP, getErrorMessage |
src/i18n/locales/{en,zh}/errors.json | Error message translations |
© microsoft, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .cursor/skills/error-handling of microsoft/data-formulator.
Open the folder on GitHubat commit 5477f0e
Error Handling next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Error Handling this skillmicrosoft/data-formulator | 18k | — | ~3.8k | Automated safety check: Pass | MIT | |
| Mole Bug Patternstw93/Mole | 70k | — | ~2k | Automated safety check: Pass | GPL-3.0 | |
| Native Data FetchingCherryHQ/cherry-studio-app | 4k | 6 repos | ~2.9k | Automated safety check: Notes | MIT | |
| Rust Best Practicesfarm-fe/farm | 5.6k | 3 repos | ~1.1k | Automated safety check: Pass | MIT | |
| R Function Input Validationtidyverse/dplyr | 5.1k | 1 repos | ~2.3k | Automated safety check: Pass | Custom licence | |
| Next Best Practicesvercel-labs/openreview | 1.7k | 18 repos | ~1k | Automated safety check: Pass | None |
tw93/Mole
A catalog of recurring bug shapes in the Mole Mac cleaner, used to review safety-sensitive diffs for deletion safety, unbounded commands, shell traps and weak tests.
CherryHQ/cherry-studio-app
A skill your agent uses when implementing or debugging ANY network request, API call, or data fetching.
farm-fe/farm
Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook.
tidyverse/dplyr
Validates arguments of exported R functions with the standalone check_* type checkers from rlang, in tidyverse style with clear error messages.
vercel-labs/openreview
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
jasonjgardner/blockbench-mcp-plugin
Zod schema validation best practices for type safety, parsing, and error handling.
microsoft/data-formulator
LLM Agent 多语言注入规范。在修改 Agent 提示词、添加新的 Agent 端点、处理用户可见的后端消息(messagecode)时使用。
microsoft/data-formulator
服务端路径安全与文件访问编码规范。在编写文件下载路由、Agent 工具(文件读取/目录列出)、数据连接器/Loader、Workspace 路径操作、沙箱配置时使用。
microsoft/data-formulator
Discover connected data sources, add new data connectors through a user-confirmed form, inspect table metadata, and run bounded read-only probes when the current workspace data is insufficient.
microsoft/data-formulator
Turn an exploration (threads, findings, charts) into a single Markdown report — note, blog post, executive summary, KPI dashboard, slide brief, or multi-section analytical report, with embedded…
microsoft/data-formulator
The analyst's built-in capabilities: data-inspection tools and the always-available actions (visualize and askuser).
Categories
统一错误处理系统。在添加 API 端点、修改错误处理、添加前端 API 调用、编写错误相关测试时使用. An agent skill from microsoft/data-formulator. Error Handling is an agent skill from microsoft/data-formulator, published by the product's own GitHub organization.
Error Handling fits situations like: tasks that involve Error handling.
Run `npx skills add microsoft/data-formulator --skill error-handling -a claude-code`. Or copy the skill folder (.cursor/skills/error-handling in microsoft/data-formulator) into .claude/skills/error-handling in your project. Claude Code loads it when a task matches its description.
Run `npx skills add microsoft/data-formulator --skill error-handling -a codex`. Or copy the skill folder (.cursor/skills/error-handling in microsoft/data-formulator) into .agents/skills/error-handling in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add microsoft/data-formulator --skill error-handling -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/error-handling, .gemini/skills/error-handling, .github/skills/error-handling and .opencode/skills/error-handling in your project.
SKILL.md names no scripts, command-line tools or credentials: Error Handling is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Error Handling is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.8k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Error Handling: Mole Bug Patterns (tw93/Mole, 70k stars), Native Data Fetching (CherryHQ/cherry-studio-app, 4k stars), Rust Best Practices (farm-fe/farm, 5.6k stars) and R Function Input Validation (tidyverse/dplyr, 5.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
microsoft (a GitHub organization, an official publisher) maintains it in microsoft/data-formulator, which has 17,540 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 8, 2026.
Source: microsoft/data-formulator on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.