Skip to main content
Glama
errors.md15.2 kB
# Error Reference Complete reference for all error codes used by the FreshBooks MCP server. All errors follow the JSON-RPC 2.0 error object specification. ## Error Response Format All errors are returned in standardized JSON-RPC 2.0 format: ```json { "jsonrpc": "2.0", "id": "request-id", "error": { "code": -32603, "message": "Human-readable error message", "data": { "freshbooksError": { "code": "NOT_FOUND", "message": "Original FreshBooks error message", "errno": 1012, "statusCode": 404 }, "recoverable": false, "suggestion": "What to do next", "context": { "tool": "timeentry_single", "accountId": "ABC123", "entityId": 99999 } } } } ``` ### Error Object Fields | Field | Type | Description | |-------|------|-------------| | code | number | MCP error code (see below) | | message | string | User-friendly error message | | data | object | Additional error details | ### Error Data Fields | Field | Type | Optional | Description | |-------|------|----------|-------------| | freshbooksError | object | Yes | Original FreshBooks API error | | validationErrors | array | Yes | Zod validation errors | | context | object | Yes | Contextual information | | recoverable | boolean | No | Whether error can be recovered from | | suggestion | string | Yes | Recommended recovery action | | retryAfter | number | Yes | Seconds to wait before retry (rate limiting) | | authUrl | string | Yes | Authorization URL (auth errors) | | statusCode | number | Yes | HTTP status code | --- ## Standard JSON-RPC Error Codes Standard error codes defined by JSON-RPC 2.0 specification. | Code | Name | Description | Recoverable | |------|------|-------------|-------------| | -32700 | Parse Error | Invalid JSON received | No | | -32600 | Invalid Request | Invalid request object | No | | -32601 | Method Not Found | Tool does not exist | No | | -32602 | Invalid Params | Invalid tool parameters | No | | -32603 | Internal Error | Internal server error | Depends | ### -32700 Parse Error **When:** Invalid JSON in request **Cause:** Malformed JSON syntax **Recovery:** Fix JSON syntax **Example:** ```json { "code": -32700, "message": "Invalid JSON was received", "data": { "recoverable": false, "suggestion": "Check JSON syntax is valid" } } ``` ### -32600 Invalid Request **When:** Request object is invalid **Cause:** Missing required fields, wrong structure **Recovery:** Fix request format **Example:** ```json { "code": -32600, "message": "The JSON sent is not a valid request", "data": { "recoverable": false, "suggestion": "Ensure request has jsonrpc, method, and id fields" } } ``` ### -32601 Method Not Found **When:** Requested tool doesn't exist **Cause:** Typo in tool name, tool not implemented **Recovery:** Use valid tool name **Example:** ```json { "code": -32601, "message": "The method does not exist or is not available", "data": { "recoverable": false, "suggestion": "Check tool name is spelled correctly", "context": { "requestedMethod": "timeentry_lis" } } } ``` ### -32602 Invalid Params **When:** Tool parameters are invalid **Cause:** Missing required params, wrong type, validation failure **Recovery:** Fix parameter values **Example:** ```json { "code": -32602, "message": "Invalid method parameters", "data": { "validationErrors": [ { "path": "accountId", "message": "Required", "code": "invalid_type", "expected": "string", "received": "undefined" }, { "path": "duration", "message": "Number must be greater than or equal to 0", "code": "too_small", "expected": "0", "received": "-100" } ], "recoverable": false, "suggestion": "Provide valid parameters matching the schema" } } ``` ### -32603 Internal Error **When:** Unexpected server error **Cause:** Various (network, FreshBooks API, server bug) **Recovery:** Depends on specific error **Example:** ```json { "code": -32603, "message": "Internal server error", "data": { "recoverable": true, "suggestion": "Retry the request" } } ``` --- ## Custom Application Error Codes Application-specific error codes (range: -32000 to -32099). | Code | Name | Description | Recoverable | |------|------|-------------|-------------| | -32001 | Not Authenticated | Authentication required | Yes | | -32002 | Token Expired | Access token expired | Yes | | -32003 | Permission Denied | Insufficient permissions | No | | -32004 | Rate Limited | API rate limit exceeded | Yes | | -32005 | Resource Not Found | Requested resource not found | No | | -32006 | Validation Error | Data validation failed | No | | -32007 | Conflict | Resource conflict (duplicate, state) | Depends | | -32008 | Service Unavailable | FreshBooks API unavailable | Yes | | -32009 | Network Error | Network communication error | Yes | | -32010 | Timeout | Request timeout | Yes | ### -32001 Not Authenticated **When:** User not authenticated **Cause:** No valid OAuth tokens **Recovery:** Call auth_get_url to authenticate **Example:** ```json { "code": -32001, "message": "Authentication required", "data": { "recoverable": true, "suggestion": "Call auth_get_url to start authentication", "authUrl": "https://my.freshbooks.com/service/auth/oauth/authorize?..." } } ``` ### -32002 Token Expired **When:** Access token expired **Cause:** Token validity period ended **Recovery:** Automatic refresh, or re-authenticate **Example:** ```json { "code": -32002, "message": "Authentication token expired", "data": { "recoverable": true, "suggestion": "Token will be automatically refreshed, please retry", "freshbooksError": { "code": "TOKEN_EXPIRED", "statusCode": 401 } } } ``` ### -32003 Permission Denied **When:** User lacks permission for operation **Cause:** OAuth scope insufficient, account restrictions **Recovery:** Re-authenticate with required scopes **Example:** ```json { "code": -32003, "message": "Permission denied", "data": { "recoverable": false, "suggestion": "Re-authenticate with required permissions", "freshbooksError": { "code": "FORBIDDEN", "message": "You do not have permission to access this resource", "statusCode": 403 } } } ``` ### -32004 Rate Limited **When:** API rate limit exceeded **Cause:** Too many requests in time window **Recovery:** Wait and retry **Example:** ```json { "code": -32004, "message": "API rate limit exceeded", "data": { "recoverable": true, "suggestion": "Wait a moment and retry the request", "retryAfter": 60, "freshbooksError": { "code": "RATE_LIMIT_EXCEEDED", "statusCode": 429 } } } ``` ### -32005 Resource Not Found **When:** Requested resource doesn't exist **Cause:** Invalid ID, resource deleted **Recovery:** Verify ID is correct **Example:** ```json { "code": -32005, "message": "Resource not found in FreshBooks", "data": { "recoverable": false, "suggestion": "Verify the resource ID and account ID are correct", "context": { "tool": "timeentry_single", "accountId": "ABC123", "timeEntryId": 99999 }, "freshbooksError": { "code": "NOT_FOUND", "message": "TimeEntry with id 99999 was not found", "errno": 1012, "statusCode": 404 } } } ``` ### -32006 Validation Error **When:** FreshBooks API validation fails **Cause:** Invalid data values, business rule violation **Recovery:** Fix data and retry **Example:** ```json { "code": -32006, "message": "Validation error from FreshBooks API", "data": { "recoverable": false, "suggestion": "Check the input parameters and try again", "freshbooksError": { "code": "VALIDATION_ERROR", "message": "Project with id 999 does not exist", "field": "projectId", "statusCode": 422 } } } ``` ### -32007 Conflict **When:** Resource conflict **Cause:** Duplicate resource, invalid state transition **Recovery:** Depends on specific conflict **Example:** ```json { "code": -32007, "message": "Resource conflict", "data": { "recoverable": true, "suggestion": "Stop existing timer first with timer_stop", "freshbooksError": { "code": "CONFLICT", "message": "A timer is already running for this user", "statusCode": 409 } } } ``` ### -32008 Service Unavailable **When:** FreshBooks API unavailable **Cause:** Maintenance, outage **Recovery:** Wait and retry **Example:** ```json { "code": -32008, "message": "FreshBooks API temporarily unavailable", "data": { "recoverable": true, "suggestion": "FreshBooks may be undergoing maintenance, try again later", "freshbooksError": { "code": "SERVICE_UNAVAILABLE", "statusCode": 503 } } } ``` ### -32009 Network Error **When:** Network communication fails **Cause:** Connection timeout, DNS failure, network unreachable **Recovery:** Check connection and retry **Example:** ```json { "code": -32009, "message": "Network communication error", "data": { "recoverable": true, "suggestion": "Check network connection and retry", "context": { "errorCode": "ENOTFOUND" } } } ``` ### -32010 Timeout **When:** Request exceeds timeout **Cause:** Slow network, large dataset, FreshBooks delay **Recovery:** Retry request **Example:** ```json { "code": -32010, "message": "Request timeout", "data": { "recoverable": true, "suggestion": "Retry the request" } } ``` --- ## FreshBooks Error Code Mapping How FreshBooks API errors map to MCP errors. | FreshBooks Code | MCP Code | Description | |-----------------|----------|-------------| | UNAUTHORIZED | -32001 | Not authenticated | | UNAUTHENTICATED | -32001 | Not authenticated | | TOKEN_EXPIRED | -32002 | Token expired | | INVALID_GRANT | -32001 | Invalid OAuth grant | | FORBIDDEN | -32003 | Permission denied | | INSUFFICIENT_PERMISSIONS | -32003 | Permission denied | | NOT_FOUND | -32005 | Resource not found | | VALIDATION_ERROR | -32006 | Validation failed | | BAD_REQUEST | -32602 | Invalid parameters | | RATE_LIMIT_EXCEEDED | -32004 | Rate limited | | CONFLICT | -32007 | Resource conflict | | INTERNAL_ERROR | -32603 | Server error | | SERVICE_UNAVAILABLE | -32008 | Service unavailable | --- ## Error Handling Best Practices ### Check Recoverable Flag ```typescript if (error.data.recoverable) { // Can retry or recover if (error.data.suggestion) { console.log("Suggestion:", error.data.suggestion); } if (error.data.retryAfter) { // Wait before retry await sleep(error.data.retryAfter * 1000); retry(); } } else { // Cannot recover, show error to user console.error(error.message); } ``` ### Handle Authentication Errors ```typescript if (error.code === -32001) { // Not authenticated const authUrl = await auth_get_url(); console.log("Please authenticate:", authUrl.authorizationUrl); } if (error.code === -32002) { // Token expired - auto-refresh happens, just retry return retry(); } ``` ### Handle Rate Limiting ```typescript if (error.code === -32004) { const retryAfter = error.data.retryAfter || 60; console.log(`Rate limited, waiting ${retryAfter} seconds...`); await sleep(retryAfter * 1000); return retry(); } ``` ### Handle Validation Errors ```typescript if (error.code === -32602) { // Invalid parameters if (error.data.validationErrors) { error.data.validationErrors.forEach(err => { console.error(`${err.path}: ${err.message}`); }); } } if (error.code === -32006) { // FreshBooks validation error const fbError = error.data.freshbooksError; console.error(`${fbError.field}: ${fbError.message}`); } ``` ### Preserve Original Errors ```typescript // Original FreshBooks error always preserved if (error.data.freshbooksError) { console.log("FreshBooks error code:", error.data.freshbooksError.code); console.log("FreshBooks message:", error.data.freshbooksError.message); console.log("HTTP status:", error.data.freshbooksError.statusCode); console.log("Error number:", error.data.freshbooksError.errno); } ``` --- ## Common Error Scenarios ### Scenario: Not Authenticated ``` timeentry_list({ accountId: "ABC123" }) Error: { "code": -32001, "message": "Authentication required", "data": { "recoverable": true, "suggestion": "Call auth_get_url to start authentication" } } Recovery: 1. Call auth_get_url() 2. User authorizes 3. Call auth_exchange_code() 4. Retry original request ``` ### Scenario: Invalid Parameter ``` timeentry_create({ accountId: "ABC123", duration: -100 }) Error: { "code": -32602, "message": "Invalid method parameters", "data": { "validationErrors": [ { "path": "duration", "message": "Number must be greater than or equal to 0" } ], "recoverable": false } } Recovery: Fix duration to positive value and retry ``` ### Scenario: Resource Not Found ``` timeentry_single({ accountId: "ABC123", timeEntryId: 99999 }) Error: { "code": -32005, "message": "Resource not found in FreshBooks", "data": { "recoverable": false, "suggestion": "Verify the time entry ID exists", "freshbooksError": { "code": "NOT_FOUND", "message": "TimeEntry with id 99999 was not found" } } } Recovery: Verify ID is correct, use timeentry_list to find valid IDs ``` ### Scenario: Timer Already Running ``` timer_start({ accountId: "ABC123", projectId: 42 }) Error: { "code": -32007, "message": "Resource conflict", "data": { "recoverable": true, "suggestion": "Stop existing timer first with timer_stop", "freshbooksError": { "code": "CONFLICT", "message": "A timer is already running" } } } Recovery: 1. Call timer_current() to find active timer 2. Call timer_stop() to stop it 3. Retry timer_start() ``` ### Scenario: Rate Limit ``` // After many rapid requests... Error: { "code": -32004, "message": "API rate limit exceeded", "data": { "recoverable": true, "suggestion": "Wait a moment and retry the request", "retryAfter": 60 } } Recovery: Wait 60 seconds and retry ``` --- ## Error Code Quick Reference | Code | Name | Recovery | |------|------|----------| | -32700 | Parse Error | Fix JSON syntax | | -32600 | Invalid Request | Fix request structure | | -32601 | Method Not Found | Use valid tool name | | -32602 | Invalid Params | Fix parameters | | -32603 | Internal Error | Retry or contact support | | -32001 | Not Authenticated | Call auth_get_url | | -32002 | Token Expired | Retry (auto-refresh) | | -32003 | Permission Denied | Re-auth with permissions | | -32004 | Rate Limited | Wait and retry | | -32005 | Not Found | Verify resource ID | | -32006 | Validation Error | Fix data values | | -32007 | Conflict | Resolve conflict | | -32008 | Service Unavailable | Wait and retry | | -32009 | Network Error | Check connection | | -32010 | Timeout | Retry request |

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Good-Samaritan-Software-LLC/freshbooks-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server