KB-3A4B

GPT ↔ Agent Data connector recurrence — root cause (2026-05-12)

14 min read Revision 1
reportgpt-connectorroot-causeopenai-action-gatewayschema-cache2026-05-12

title: GPT ↔ Agent Data connector recurrence — root cause investigation date: 2026-05-12 investigator: Claude Code (Opus 4.7) status: ROOT_CAUSE_IDENTIFIED schema_version_active: gpt-agent-data-2026-05-12.1 rest_schema_hash: aaec3d401df2 mcp_schema_hash: 5f13902e975a

GPT ↔ Agent Data connector — recurrence root cause (2026-05-12)

1. Câu trả lời ngắn

Root cause: lỗi nằm ngoài VPS, tại OpenAI action-gateway của Custom GPT — request KHÔNG bao giờ rời được hạ tầng OpenAI.

  • Server, nginx, agent-data, Qdrant, PostgreSQL đều healthy trong toàn bộ window điều tra.
  • 5 GPT calls user trigger tại ~06:50-06:55 UTC ngày 2026-05-12 đều báo ClientResponseError ở GPT-side.
  • Trong cùng window 5/5 calls đó, server logs ghi nhận 0 (zero) request từ OpenAI action-gateway IPs.
  • Connector_call wrapper distribution trong window 06:45-06:55 UTC: chỉ 32 healthCheck (toàn bộ là Uptime-Kuma + internal probes); 0 searchKnowledge, 0 listDocuments, 0 getDocumentTruncated.

Server không thể "fix" cái này. Phải reimport schema bên GPT Builder (xem §6).

2. Timeline tuyệt đối (UTC + ICT)

UTC ICT Sự kiện Nguồn
2026-05-12 04:05:07 11:05:07 Static /api/openapi.json được Codex viết lên disk (mtime). Size 27833 bytes. stat /opt/incomex/docker/nginx/static/openapi.json
2026-05-12 04:13:xx 11:13 agent_data/server.py được Codex sửa (mtime = May 12 06:13 CEST = 04:13 UTC). Owner UID 501 (host nmhuyen user). ls -la agent_data/server.py
2026-05-12 04:14:27 11:14:27 Container incomex-agent-data restart (RestartCount=0, ExitCode=0 fresh start). CONNECTOR_SCHEMA_VERSION="gpt-agent-data-2026-05-12.1" load vào tiến trình. docker inspect
2026-05-12 04:15:17 11:15:17 healthCheck PASS (response_bytes=577, schema_version đúng). agent-data log
2026-05-12 04:15:52 11:15:52 listDocuments với ?path= → 400 WRONG_QUERY_PARAMETER (schema cũ bị reject đúng thiết kế). agent-data log
2026-05-12 04:15:53 11:15:53 GPT retry với ?prefix= → 200 OK 808 bytes. Wrapper map đúng. agent-data log
2026-05-12 04:16:02 11:16:02 searchKnowledge (qua /mcp/tools/call) → 200 OK 5841 bytes, schema_version=gpt-agent-data-2026-05-12.1 schema_hash=5f13902e975a. agent-data log
2026-05-12 04:16:07 11:16:07 listDocuments(prefix=notes,limit=50) → 200 OK 808 bytes (2 docs). agent-data log
2026-05-12 04:19:46 11:19:46 listDocuments(prefix=reviews,limit=50) → 200 OK 17218 bytes (50 of 517). agent-data log
2026-05-12 04:20:xx 11:20 Last successful GPT-action-gateway hit (172.18.0.7 proxied). Sau đó không còn request từ OpenAI IP ranges. nginx + agent-data
2026-05-12 06:00-06:38 13:00-13:38 "30 phút qua" theo user. 0 request ChatGPT-User/1.0 đến server. nginx 30m grep
2026-05-12 06:50-06:55 13:50-13:55 User trigger 5 GPT calls. Server window: 0 ChatGPT-User, 0 OpenAI gateway IP, 0 connector_call non-health. live tail b48bd8ccb + bjd0ziat7

3. Evidence table — 5 GPT calls user triggered

GPT call request seen ở server? route method query/body keys status bytes schema version/hash conclusion
(a) healthCheck KHÔNG (không có request từ OpenAI IP trong cửa sổ 06:47-06:55) - - - - - - Failure trước VPS
(b) searchKnowledge("OGV-2C write gate a40b217") KHÔNG - - - - - - Failure trước VPS
(c) getDocumentTruncated("…stability-fix-2026-05-12.md") KHÔNG - - - - - - Failure trước VPS
(d) listDocuments(prefix=notes) KHÔNG - - - - - - Failure trước VPS
(e) listDocuments(prefix=reviews) KHÔNG - - - - - - Failure trước VPS

Verification: unique external client IPs reach nginx trong cuối 10 phút (gồm cả window trigger):

123.24.178.152   (Vietnam — user / Claude Code / their browser)
157.55.39.52     (bingbot)
172.18.0.1       (internal docker bridge — uptime-kuma)
38.242.240.89    (VPS internal probe — curl/8.5.0 uptime-kuma loop)

OpenAI action-gateway IP ranges (đã thấy trong logs cũ): 172.196.40.x, 13.76.115.x, 20.210.174.x, 172.196.xkhông có IP nào trong window trigger.

Connector_call wrapper distribution trong window 06:45-06:55 UTC:

     32 healthCheck   ← toàn bộ là Uptime-Kuma + internal probes (172.18.0.x)
      0 searchKnowledge
      0 listDocuments
      0 getDocumentTruncated
      0 getDocument
      0 createDocument

4. Phân loại theo CASE A-F (yêu cầu của bạn)

  • CASE A ✅ APPLIES: Không thấy request tới VPS → lỗi trước VPS: GPT action-gateway/schema cache/connector.
  • CASE B ❌ ruled out: Không có server-200-then-GPT-ClientResponseError nào trong window.
  • CASE C ❌ ruled out: Không có 400 (mặc dù schema cũ ?path= vẫn sẽ 400 đúng thiết kế, nhưng không có request nào reach).
  • CASE D ❌ ruled out: Không có 401/403 (server không nhận request để mà auth-fail).
  • CASE E ❌ ruled out: Không có 413/429/5xx/timeout từ OpenAI IPs. Server tự test internal MCP probe 200 OK liên tục.
  • CASE F ⚠️ informational: 2 surfaces tồn tại (REST /api/chat+/api/documents/* vs MCP /api/mcp), 2 schema hash riêng (REST aaec3d401df2 vs MCP 5f13902e975a). Có liên quan tới root cause vì user/Codex tin một số fact của một surface áp dụng cho surface khác — xem §5.

5. Phân biệt H1-H6 hypothesis

H Giả thuyết PASS/FAIL Bằng chứng
H1 Stale OpenAPI schema cache ở GPT CONFIRMED khả năng cao GPT đã PASS lúc 04:15-04:20 với schema mới; sau session ngắn không còn request reach server; nếu schema cache hỏng/expired và refresh fail, gateway short-circuit ClientResponseError tất cả tools.
H2 Idle session/token expiry GPT PARTIAL Không thấy 401/403 ở server vì không có request — nhưng nếu OpenAI gateway cached invalid auth, nó sẽ short-circuit thay vì gọi server.
H3 Parser/body-limit connector RULED OUT healthCheck (530 bytes) cũng fail. Không thể là body-limit.
H4 Server-side 4xx/5xx RULED OUT Trong 12h liên tiếp: 489/489 healthCheck 200; 0 5xx; 0 timeout từ agent-data; nginx error.log không có gì ngoài "buffered to temp file" cosmetic warning.
H5 Schema race/cached wrapper drift CONTRIBUTING Có thật 2 schema cùng tồn tại: REST OpenAPI version 1.2.0 hash aaec3d401df2 (info field), MCP wrapper hash 5f13902e975a (dynamic). Connector_call log emit MCP hash; OpenAPI info emit REST hash. User/Codex thấy 5f13902e975a ở 1 chỗ, aaec3d401df2 ở chỗ khác → confusion về schema_hash.
H6 MCP vs REST dual-surface conflict CONFIRMED architecture-level REST routes: /api/health, /api/kb/list, /api/documents/*, /api/chat. MCP route: /api/mcp. ChatGPT-User/1.0 (OpenAI bot) đã từng dùng /api/chat+/api/documents/batch (REST). Connector fix mới thêm /api/kb/list+/api/mcp. searchKnowledge map qua POST /chat ở openapi.json, nhưng cũng có thể qua MCP tools/call ở MCP surface — 2 đường dẫn khác nhau cho cùng 1 tool name.

6. Root cause (phát biểu chính thức)

Tại sao sau khi PASS, GPT lại FAIL sau một thời gian?

GPT custom action có một "action gateway" do OpenAI vận hành nằm giữa LLM và HTTP server của ta. Gateway này:

  1. Cache OpenAPI schema (đã import qua URL config trong GPT Builder).
  2. Cache connection pool + DNS + TLS session về server đích.
  3. Cache auth (API key) cùng với schema.

Khi user import schema lần đầu (hoặc fix push xong, user re-import), một entry mới được tạo. Trong session đầu (04:15-04:20 UTC) gateway dispatch HTTP đến server bình thường — PASS.

Sau khoảng idle / sau session reset / sau khi schema cache TTL trên gateway của OpenAI hết hạn, gateway thử refresh schema bằng cách fetch lại OpenAPI URL đã cấu hình:

  • Nếu URL config là https://vps.incomexsaigoncorp.vn/api/openapi.json → 200 OK 27833 bytes (đường này hoạt động).
  • Nếu URL config là https://vps.incomexsaigoncorp.vn/api/chatgpt-openapi.json301 Moved Permanently → Location: /openapi.json (mất tiền tố /api/). OpenAI's action gateway resolve relative redirect tới https://vps.incomexsaigoncorp.vn/openapi.json (root nuxt frontend) → 404 từ nuxt. Schema refresh fail → toàn bộ tool dispatch fail ClientResponseError.
  • Nếu URL config là cái cũ trước fix có endpoint chỉ tồn tại trên surface MCP → gateway refresh thấy schema mismatch / unknown tool name → ClientResponseError.

Có thể cũng kèm theo các yếu tố khác (TLS session reuse hỏng, API key bị OpenAI gateway invalidate sau X giờ idle), nhưng dấu hiệu phổ biến của OpenAI Custom GPT "PASS rồi FAIL sau idle ngắn" là schema cache refresh thất bại.

Routes đáng nghi tại nginx:

HEAD /api/openapi.json         → 200 OK, 27833 bytes, Last-Modified 04:05:07 UTC ✓
HEAD /api/chatgpt-openapi.json → 405 Method Not Allowed (allow: GET)
GET  /api/chatgpt-openapi.json → 301 Moved Permanently → Location: /openapi.json (mất /api/ prefix → nuxt 404)

Route /chatgpt-openapi.json tồn tại bên trong agent-data (FastAPI route trên port 8000 — @app.get("/chatgpt-openapi.json", include_in_schema=False)), nhưng không có nginx location block expose nó công khai. Nó bị catch-all rewrite về /openapi.json (mất /api/).

7. Các giả thuyết đã loại trừ

Giả thuyết Lý do loại
Server crash/OOM RestartCount=0, ExitCode=0, started fresh 04:14:27 UTC, đến nay 2.5h liên tục Up healthy
Qdrant/PG mất Tất cả probe 200 OK liên tục mỗi 30s với latency 1-26ms
Rate-limit nginx Không có 429 nào trong toàn bộ 24h
Body size 413 Không có 413 nào; agent-data response_bytes max thấy là 54603 (documents/batch), 17218 (list reviews) — đều dưới ngưỡng
TLS cert expired TLS handshake từ nhiều bot vẫn 200 OK
Đụng Qdrant/PG/OGV-2C rollback Không có log nào chứng minh — KHÔNG TOUCH

8. Fix recommendation

Cấp 1 — User action (Critical, fix root cause):

  1. Mở GPT Builder → Configure → Actions → schema cũ.
  2. Kiểm tra URL schema GPT đang import. Nó phảihttps://vps.incomexsaigoncorp.vn/api/openapi.json. Nếu là /api/chatgpt-openapi.json hoặc gì khác → đổi sang /api/openapi.json.
  3. Bấm "Import" / "Refresh" để force re-fetch schema. Save action.
  4. Test ngay 5 calls; nếu pass thì để 15 phút idle rồi test lại.

Cấp 2 — Defense in depth (nên làm):

  1. Thêm nginx location alias để /api/chatgpt-openapi.json cũng serve cùng file static như /api/openapi.json (defensive route — phòng GPT config trỏ tới URL cũ):
    location = /api/chatgpt-openapi.json {    alias /usr/share/nginx/static/openapi.json;    add_header Cache-Control "no-cache, must-revalidate";    add_header Access-Control-Allow-Origin "*";}
    
  2. Đồng bộ x-connector-schema-hash giữa REST OpenAPI (aaec3d401df2) và MCP wrapper (5f13902e975a). Hiện 2 hash khác nhau gây confusion — chỉ giữ 1 nguồn truth (đề xuất: dùng REST hash, MCP wrapper compute lại từ cùng OpenAPI).
  3. Thêm endpoint debug /api/connector-info trả về JSON với {schema_version, rest_hash, mcp_hash, openapi_url, last_reload} để GPT/dev có cách verify cache trạng thái.

Cấp 3 — KHÔNG nên làm:

  • KHÔNG rollback OGV-2C — không có log nào chứng minh OGV-2C gây lỗi.
  • KHÔNG restart Qdrant/PG — chúng healthy.
  • KHÔNG restart agent-data — container đang chạy ổn định Up 2h và serving 200 OK liên tục.
  • KHÔNG sửa Directus — không liên quan.

9. Long-idle acceptance test plan (sau khi user reimport)

Round A (immediate sau reimport):

  • (1) healthCheck
  • (2) searchKnowledge("OGV-2C write gate a40b217")
  • (3) getDocumentTruncated("knowledge/current-state/reports/gpt-agent-data-connector-stability-fix-2026-05-12.md")
  • (4) listDocuments(prefix="knowledge/dev/laws/dieu44-trien-khai/notes")
  • (5) listDocuments(prefix="knowledge/dev/laws/dieu44-trien-khai/reviews")

Round B: 5 phút idle, lặp 5 calls. Round C: 15 phút idle, lặp 5 calls. Round D: ngay sau D4/D5 lớn 50 bytes, gọi searchKnowledge. Round E: nếu OpenAI action-gateway có cơ chế force-reload, force-reload và test lại.

PASS criteria:

  • Mọi round 5/5 không ClientResponseError.
  • Server logs cho thấy request đến từ OpenAI gateway IP (172.196.x hoặc tương đương) trong cùng timestamp.
  • response_bytes match expected size theo schema version.
  • Nếu Round C fail trong khi Round A pass → vẫn còn schema/connection cache issue ở OpenAI side, không phải server.

10. Có cần GPT UI reimport schema thủ công không?

CÓ — bắt buộc. Đây là kết luận từ evidence.

Server-side đã đúng từ 04:14 UTC ngày 2026-05-12. Mọi PASS đã ghi nhận đều có request reach server và 200 OK. Mọi FAIL hiện tại có chung dấu vân tay "request không reach server" → bắt buộc fix ở chỗ phát request, tức GPT Builder bên OpenAI.

11. Biện pháp ngăn tái phát

  1. Tài liệu hóa URL schema chính thức của GPT: https://vps.incomexsaigoncorp.vn/api/openapi.json. Ghi vào README của repo agent-data + onboarding doc.
  2. Thêm nginx alias cho /api/chatgpt-openapi.json (defense in depth — không sửa root cause nhưng phòng misconfig).
  3. Mỗi khi push connector schema version mới (bump CONNECTOR_SCHEMA_VERSION trong server.py), update static file /opt/incomex/docker/nginx/static/openapi.json cùng commit + restart agent-data + note rõ trong report: cần user reimport bên GPT Builder.
  4. Thêm uptime probe đo /api/openapi.json response status + Last-Modified, alert nếu file mtime drift quá xa container start time.
  5. Sync REST schema hash và MCP schema hash về 1 nguồn duy nhất.

Investigator note: Báo cáo này dựa hoàn toàn trên log VPS thật từ 2026-05-11 06:30 UTC tới 2026-05-12 06:55 UTC, không dùng curl thay GPT làm bằng chứng. Round A curl test ở §6 chỉ để verify route behavior (HEAD/GET 301), không để chứng minh GPT pass/fail.

Back to Knowledge Hub knowledge/current-state/reports/gpt-agent-data-connector-recurrence-root-cause-2026-05-12.md