{"record":{"id":"f3c8ae905635c64a","repo":"apache/seatunnel","slug":"airtable-api-request-failed-status-code-s-con","errorCode":null,"errorMessage":"Airtable API request failed, status code:[%s], content:[%s]","messagePattern":"Airtable API request failed, status code:\\[(.+?)\\], content:\\[(.+?)\\]","errorType":"http","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-http/connector-http-airtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/airtable/sink/AirtableSinkWriter.java","lineNumber":151,"sourceCode":"                }\n                if (response.getCode() == STATUS_TOO_MANY_REQUESTS\n                        && retryCount < rateLimitMaxRetries) {\n                    retryCount++;\n                    long backoffMillis = calculateBackoffMillis(retryCount);\n                    log.warn(\n                            \"Airtable API rate limit reached, retry {}/{} after {} ms\",\n                            retryCount,\n                            rateLimitMaxRetries,\n                            backoffMillis);\n                    try {\n                        Thread.sleep(backoffMillis);\n                    } catch (InterruptedException e) {\n                        Thread.currentThread().interrupt();\n                        throw new RuntimeException(e);\n                    }\n                    continue;\n                }\n                throw new IOException(\n                        String.format(\n                                \"Airtable API request failed, status code:[%s], content:[%s]\",\n                                response.getCode(), response.getContent()));\n            } catch (IOException e) {\n                throw e;\n            } catch (Exception e) {\n                throw new IOException(\"Failed to send Airtable API request\", e);\n            }\n        }\n    }\n\n    private void waitForRequestSlot() {\n        if (requestIntervalMs <= 0) {\n            return;\n        }\n        long now = System.currentTimeMillis();\n        long elapsed = now - lastRequestTimeMillis;\n        if (elapsed < requestIntervalMs) {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-http/connector-http-airtable/src/main/java/org/apache/seatunnel/connectors/seatunnel/airtable/sink/AirtableSinkWriter.java#L133-L169","documentation":"AirtableSinkWriter.sendWithRateLimitRetry throws this IOException when the Airtable HTTP API returns a non-success, non-rate-limit status code. The message embeds the HTTP status and response body so you can see exactly why Airtable rejected the request (auth, bad table id, invalid payload, etc.).","triggerScenarios":"Any Airtable API response with an error status that was not retried as 429: e.g. 401 invalid token, 403 forbidden, 404 unknown base/table, 422 invalid field value in the record payload.","commonSituations":"Expired or wrong personal access token, typo'd baseId/tableId in sink config, writing a record whose fields don't match the Airtable table schema, or Airtable-side outages returning 5xx.","solutions":["Read the status code and content in the message: 401/403 → fix the Airtable API token and its scopes; 404 → correct baseId/tableId.","For 422, align the SeaTunnel row fields/types with the Airtable table columns.","Retry after transient 5xx; check https://status.airtable.com for outages.","Increase or respect rate limiting so requests aren't rejected."],"exampleFix":"// before: sink config with bad table id\nbaseId = appXXXXXXXXXXXX\ntableId = WrongTable\n// after\nbaseId = appXXXXXXXXXXXX\ntableId = tblRealTableId (copied from Airtable API docs URL)","handlingStrategy":"validation","validationCode":"// Pre-check before running the job\ncurl -s -o /dev/null -w \"%{http_code}\" -H \"Authorization: Bearer $AIRTABLE_TOKEN\" \"https://api.airtable.com/v0/$BASE_ID/$TABLE_ID?maxRecords=1\" # expect 200","typeGuard":null,"tryCatchPattern":"try { sinkWriter.prepareCommit(); } catch (RuntimeException e) { /* inspect cause IOException message for status code/content */ }","preventionTips":["Validate token and scopes with a test API call","Copy baseId/tableId directly from the Airtable API URL","Match row fields to the table schema","Monitor https://status.airtable.com"],"tags":["http","airtable","api-error"],"backgroundTag":"http-error-response","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}