1.8 KiB
1.8 KiB
Error Model
Stable categories
AUTHENTICATION_REQUIREDTOKEN_INVALIDACCESS_DENIEDPROJECT_NOT_FOUNDRESOURCE_NOT_REGISTEREDCONNECTOR_DISABLEDCONNECTOR_UNAVAILABLETARGET_UNAVAILABLEVALIDATION_FAILEDRATE_LIMITEDTIMEOUTRESULT_TOO_LARGEUPSTREAM_PROTOCOL_ERRORINTERNAL_ERROR
Response rules
- do not reveal whether a forbidden resource exists when that leaks scope;
- include a trace ID;
- use retryability metadata;
- keep user-facing messages useful but sanitized;
- log detailed internal exceptions only in protected logs;
- translate target-specific errors into stable categories while preserving a safe diagnostic code.
- separate
retryablefromsafeToRetry: transient writes may be retryable only after their exact state is reconciled, never by blind transport replay; - identify the failed operation and subsystem without returning target URLs, credentials, raw headers or stack traces;
- include expected/actual state and a bounded recovery hint when optimistic state changed;
- keep the stateless MCP session usable after an operation error.
Example:
{
"error": {
"code": "CONNECTOR_UNAVAILABLE",
"category": "transient",
"message": "The Unraid inventory connector is temporarily unavailable.",
"operation": "unraid.container.health",
"subsystem": "upstream_unraid",
"retryable": true,
"safeToRetry": true,
"correlationId": "...",
"sessionId": null,
"upstreamStatus": 503,
"expectedState": null,
"actualState": null,
"recoveryHint": "Retry the unchanged read after the bounded backoff."
}
}
The dataplane retries only MCP protocol reads and catalogued R1 tools, once. Connector-local Gitea GETs use at most three bounded attempts. R2, R3 and unknown operations are never automatically retried.