# How Error Handling Works in OpenAI Plugins: Runtime, Schema, and Implementation

> Understand OpenAI plugin error handling. Learn about the runtime wrapper, OpenAPI schema validation, and developer-defined error objects to build robust plugins.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: deep-dive
- Published: 2026-07-05

---

**OpenAI plugin error handling operates through three distinct layers: a runtime wrapper that catches uncaught exceptions, an OpenAPI specification that validates error schemas, and developer-controlled logic that returns structured error objects for anticipated failures.**

OpenAI plugins execute user-provided skill scripts inside a sandboxed runtime that demands strict error handling protocols. According to the openai/plugins repository, every plugin endpoint must return either a successful result or a standardized `error` object defined in the OpenAPI specification. This architecture ensures that Python, TypeScript, and other language implementations provide consistent, machine-readable feedback to client applications.

## The Three Layers of OpenAI Plugin Error Handling

### Runtime Wrapper: Catching Uncaught Exceptions

Every skill script executes inside an automatic async IIFE wrapper that intercepts unhandled exceptions before they crash the process. As defined in [`plugins/figma/skills/figma-use/references/plugin-api-standalone.d.ts`](https://github.com/openai/plugins/blob/main/plugins/figma/skills/figma-use/references/plugin-api-standalone.d.ts), this wrapper translates runtime exceptions into structured JSON payloads and assigns appropriate HTTP status codes. When an uncaught error occurs, the wrapper returns a 5xx response containing an `error` object with code `"internal"` and the exception message.

### OpenAPI Specification: Schema Validation

Each plugin ships with an OpenAPI specification referenced in its [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) configuration file, such as [`plugins/google-calendar/.app.json`](https://github.com/openai/plugins/blob/main/plugins/google-calendar/.app.json). The specification defines a `default` response schema that mandates error objects include `code`, `message`, and optional `details` fields. The OpenAI server validates every response against this schema, forwarding non-2xx responses to the client as standardized plugin errors. This layer ensures that error formats remain consistent across all supported languages.

### Developer-Controlled Error Handling

Within skill scripts, developers implement explicit try-catch blocks to handle anticipated failures like network timeouts or API authentication errors. The [`plugins/zotero/skills/zotero/scripts/zotero.py`](https://github.com/openai/plugins/blob/main/plugins/zotero/skills/zotero/scripts/zotero.py) file demonstrates this pattern by catching `requests.HTTPError` and returning 4xx client error payloads with descriptive messages. For transient failures, the runtime may attempt automatic retries, but persistent errors propagate unchanged to the client.

## Error Response Format and HTTP Status Codes

OpenAI plugins use a standardized JSON structure for all error responses. The payload must contain an `error` object with the following structure:

- `code`: A string identifier such as `"internal"` for server errors or `"client"` for request issues
- `message`: A human-readable description of the failure
- `details` (optional): Additional contextual information

HTTP status codes indicate the error category:

- **5xx**: Internal runtime errors caught by the wrapper
- **4xx**: Client errors handled explicitly by the developer

## Practical Implementation Examples

### Python Error Handling (Zotero Plugin)

The [`plugins/zotero/skills/zotero/scripts/zotero.py`](https://github.com/openai/plugins/blob/main/plugins/zotero/skills/zotero/scripts/zotero.py) file demonstrates handling API-specific and unexpected errors:

```python
import json
import requests

def fetch_items():
    try:
        resp = requests.get("https://api.zotero.org/users/123/items")
        resp.raise_for_status()
        return {"data": resp.json()}
    except requests.HTTPError as exc:
        # Known API error – return a client‑error payload

        return {"error": {"code": "client", "message": str(exc)}}
    except Exception as exc:
        # Unexpected error – surface as internal error

        return {"error": {"code": "internal", "message": str(exc)}}

```

### TypeScript Error Handling (Figma Plugin)

```typescript
export async function run(context: PluginContext) {
  try {
    const nodes = await figma.currentPage.findAll(node => node.type === "RECTANGLE");
    return { data: nodes.map(n => n.id) };
  } catch (err) {
    // Propagate the error to the OpenAI platform
    return { error: { code: "internal", message: (err as Error).message } };
  }
}

```

## Key Files and Best Practices

Several files in the openai/plugins repository illustrate advanced error handling patterns:

- **[`plugins/figma/skills/figma-use/references/plugin-api-standalone.d.ts`](https://github.com/openai/plugins/blob/main/plugins/figma/skills/figma-use/references/plugin-api-standalone.d.ts)**: Documents the runtime's async IIFE wrapper and automatic exception translation
- **[`plugins/zotero/skills/zotero/scripts/zotero.py`](https://github.com/openai/plugins/blob/main/plugins/zotero/skills/zotero/scripts/zotero.py)**: Demonstrates explicit try-except blocks for API error handling  
- **[`plugins/cloudflare/skills/workers-best-practices/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/cloudflare/skills/workers-best-practices/SKILL.md)**: Discusses `passThroughOnException` versus explicit error return patterns
- **[`plugins/zoom/skills/video-sdk/windows/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/video-sdk/windows/SKILL.md)**: Recommends separating session initialization from audio setup to improve error isolation

## Summary

- The runtime wrapper catches all uncaught exceptions and formats them as 5xx internal errors with code `"internal"`
- OpenAPI specifications define the required error schema, validated by the OpenAI server against the `default` response definition
- Developers should handle anticipated failures explicitly, returning 4xx client errors with descriptive `message` values
- Error objects must include `code` and `message` fields, with optional `details` for additional context
- Transient failures may trigger automatic runtime retries, while persistent errors propagate unchanged to the client

## Frequently Asked Questions

### What happens if a skill script throws an uncaught exception?

The runtime wrapper automatically catches the exception and returns a JSON payload with HTTP status 5xx. The response contains an `error` object with code `"internal"` and the exception message, preventing the plugin process from crashing while surfacing the failure to the client.

### How does the OpenAI platform validate error responses?

The platform checks every response against the `default` response schema defined in the plugin's OpenAPI specification (referenced in files like [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)). If the response structure doesn't match the expected `error` object format with `code` and `message` fields, the platform maps non-2xx responses to the client's `error` field according to the schema definition.

### Can developers implement retry logic for transient failures?

While the runtime may automatically retry certain transient failures, developers should handle expected error conditions explicitly using try-catch blocks. For network operations, implement specific exception handling for timeouts and connection errors, returning appropriate 4xx status codes for client-side issues that require user intervention.

### What is the difference between internal and client error codes?

Internal errors (code `"internal"`) indicate unhandled exceptions or runtime failures, typically surfacing as 5xx HTTP responses generated by the wrapper. Client errors (code `"client"`) represent anticipated failure modes like invalid authentication tokens or bad parameters, returned as 4xx responses with descriptive messages that help users correct their requests according to the OpenAPI spec.