How to Handle Errors in an OpenAI Plugin: Complete Implementation Guide
OpenAI plugins handle errors by wrapping skill logic in try-except blocks and returning a standardized JSON payload with "ok": false, a numeric error code, and a safe user-facing message, as implemented in the openai/plugins repository.
OpenAI plugins are structured as collections of independent skills that require consistent error handling to communicate failures to the ChatGPT model. The openai/plugins repository establishes a strict error-handling contract that every skill must follow to ensure predictable, secure error responses. This guide explains the implementation pattern using actual source files from the repository.
The OpenAI Plugin Error-Handling Contract
Every skill in the repository follows a consistent contract to ensure the runtime can reliably parse success and failure states.
Standardized JSON Response Structure
On failure, skills must return a JSON object with an "ok": false field and an "error" object containing a numeric code and human-readable message. According to the UKB-TOPMed PheWAS skill documentation in plugins/life-science-research/skills/ukb-topmed-phewas-skill/SKILL.md, the contract requires:
{
"ok": false,
"error": {
"code": 400,
"message": "Human-readable description",
"details": {}
}
}
The "details" field is optional and should be omitted for privacy-critical errors.
Error Code Mapping and Security
Plugins map exceptions to stable HTTP-style error codes: 400 for bad input, 404 for not found, 500 for internal failures, and 502 for upstream service errors. The error message must never include stack traces, API keys, or internal tokens. As implemented in plugins/zotero/skills/zotero/scripts/zotero.py, sensitive information is filtered out to comply with OpenAI security policies while exceptions are logged internally for operator observability.
The _error.py Utility Implementation
The repository provides a shared utility to standardize error construction across all skills.
Centralized Error Builder
The build_error_response helper function is located at plugins/<plugin-name>/skills/<skill-name>/scripts/_error.py. This utility is explicitly defined in plugins/zotero/skills/zotero/scripts/_error.py and plugins/nvidia/skills/omniverse-cad-to-simready/shared/_error.py:
def build_error_response(exc: Exception, code: int = 500) -> dict:
"""Return a JSON-serialisable error payload."""
# Never expose internal traceback – only the message.
return {
"ok": False,
"error": {
"code": code,
"message": str(exc),
},
}
Integration in Skill Scripts
Each skill imports this helper and wraps its main logic in a try-except block. The Zotero skill in plugins/zotero/skills/zotero/scripts/zotero.py demonstrates this pattern:
from _error import build_error_response
import logging
def fetch_item(item_id: str):
try:
# ... network call to Zotero ...
return {"ok": True, "item": data}
except requests.HTTPError as exc:
logging.exception("Zotero API failure")
return build_error_response(exc, code=502)
except Exception as exc:
logging.exception("Unexpected Zotero error")
return build_error_response(exc)
Real-World Error Handling Examples
The repository contains multiple implementations demonstrating how to handle different failure modes.
Life Science Research Skills
The UKB-TOPMed PheWAS skill in plugins/life-science-research/skills/ukb-topmed-phewas-skill/scripts/ukb_topmed_phewas.py maps specific exceptions to appropriate status codes:
import json
from _error import build_error_response
def main():
try:
# Parse input, call remote API, gather results ...
result = {"association": [...]}
return {"ok": True, "data": result}
except ValueError as exc: # e.g. malformed request
return build_error_response(exc, code=400)
except ConnectionError as exc: # e.g. external service down
return build_error_response(exc, code=502)
except Exception as exc: # unexpected bug
return build_error_response(exc) # defaults to 500
NVIDIA Omniverse Skills
The NVIDIA "Omniverse CAD → SimReady" skill uses the shared utility at plugins/nvidia/skills/omniverse-cad-to-simready/shared/_error.py. The file plugins/nvidia/skills/omniverse-cad-to-simready/shared/simready_package_check_dependencies.py demonstrates converting raised exceptions into structured error responses while maintaining debuggability through internal logging.
Summary
- Return consistent shapes: Always return
{"ok": false, "error": {...}}for failures and{"ok": true, ...}for successes. - Use the helper: Import
build_error_responsefrom_error.pyto ensure consistent payload structure. - Map codes appropriately: Use
400for client errors,404for missing resources,502for upstream failures, and500for internal errors. - Secure by default: Never expose stack traces, API keys, or tokens in error messages; log these internally using
logging.exception(). - Document in SKILL.md: Each skill defines its error contract in its
SKILL.mdfile, such asplugins/zotero/skills/zotero/SKILL.md.
Frequently Asked Questions
What JSON structure should error responses follow in OpenAI plugins?
Error responses must return a JSON object with "ok": false and an "error" object containing "code" (integer), "message" (string), and optionally "details" (dictionary). This contract is documented in skill definition files like plugins/life-science-research/skills/ukb-topmed-phewas-skill/SKILL.md and enforced by the build_error_response utility.
Where is the error handling utility located in the openai/plugins repository?
The shared helper is typically located at plugins/<plugin-name>/skills/<skill-name>/scripts/_error.py. Specific implementations exist in plugins/zotero/skills/zotero/scripts/_error.py and plugins/nvidia/skills/omniverse-cad-to-simready/shared/_error.py, which are imported by individual skill scripts to standardize error formatting.
How do OpenAI plugins prevent sensitive data leaks in error messages?
Plugins use the build_error_response function to ensure only the exception message is returned, omitting stack traces and secret values. Internal details are logged using logging.exception() for operator visibility, while the JSON response contains only user-safe text, as required by the OpenAI security policies implemented in the plugin runtime.
What error codes should OpenAI plugin skills return?
Use standard HTTP-style codes: 400 for client input errors, 404 for missing resources, 502 for upstream service failures (like external API outages), and 500 for unexpected internal errors. The Zotero skill in plugins/zotero/skills/zotero/scripts/zotero.py demonstrates mapping specific exceptions like requests.HTTPError to code 502.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →