Skip to content

fix(openapi): extract success responses declared with wildcard 2XX status keys#1275

Merged
RhysSullivan merged 1 commit into
mainfrom
fix/msgraph-content-binary
Jul 3, 2026
Merged

fix(openapi): extract success responses declared with wildcard 2XX status keys#1275
RhysSullivan merged 1 commit into
mainfrom
fix/msgraph-content-binary

Conversation

@RhysSullivan

Copy link
Copy Markdown
Owner

Microsoft Graph's OpenAPI spec declares every success response under the OpenAPI wildcard status key 2XX — 13k+ occurrences, with no numeric 200/201 keys anywhere in the 37MB document. The extractor's success-response filter only matched exact /^2\d\d$/ codes, so no response body (and no file hint) was ever extracted for any Graph operation.

Concretely: drive item content downloads (drivesGetItemsContent, /me/drive/items/{id}/content) already carry format: binary in Microsoft's spec, but the missing 2XX handling meant the binaryResponse hint never surfaced, so binary bodies were returned as lossy text instead of ToolFile artifacts.

Changes:

  • extractResponseBody now accepts wildcard 2XX keys, ranked after exact 2xx codes and before default.
  • Microsoft Graph spec build normalizes octet-stream success responses that carry a non-binary schema (report-style endpoints declare type: object with a value property there) to type: string, format: binary, and full-graph selections now flow through the same path-item transform.
  • Tests: fixtures model the real Graph shapes (2XX keys, $ref'd error responses, path-level parameters), assert the streamed binding for a content GET yields a binaryResponse file hint, plus a focused extractor test in the openapi package.
  • Cloudflare extraction baseline gains one operation whose success response is declared as 2XX (previously silently dropped).

Note for deployment: compiled bindings are persisted at spec registration time, so existing registered Microsoft Graph integrations need a spec refresh/re-registration to pick up the fix.

…atus keys

Microsoft Graph's OpenAPI spec declares every success response under the
wildcard status key 2XX (13k+ occurrences, no numeric 200/201 keys at all),
which the extractor's /^2\d\d$/ filter skipped entirely. No response body
or file hint was ever extracted for Graph operations, so drive content
downloads never took the binaryResponse ToolFile path and came back as
lossy text. Accept 2XX between exact codes and default.

Also normalize Microsoft Graph octet-stream success responses that carry a
non-binary schema (report-style endpoints declare type: object there) to a
binary string during spec build, and run full-graph selections through the
same path-item transform. The Cloudflare extraction baseline gains one
operation whose success response is declared as 2XX.
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown

Greptile Summary

Fixes silent loss of response bodies for Microsoft Graph operations by teaching extractResponseBody to recognize the OpenAPI 2XX wildcard status key (Graph uses this for every success response, with zero numeric 200/201 keys in the 37MB spec). A companion normalization pass in graph.ts rewrites report-style octet-stream responses whose schema is type: object (a value wrapper) to type: string, format: binary, so the extractor can emit a binaryResponse file hint for binary downloads.

  • extract.ts: preferred response list now includes a 2XX-wildcard tier between exact codes and default; case-insensitive to handle both 2XX and 2xx.
  • graph.ts: normalizeMicrosoftGraphContentPathItem rewrites non-binary octet-stream schemas to binary in success responses; microsoftGraphKeepPathItem signature changed from KeepPathItem | undefined to always KeepPathItem, so the normalization runs even for full-graph selections that previously returned undefined.
  • Tests: new fixtures mirror real Graph shapes (wildcard keys, $ref error responses, path-level parameters); snapshot bumps Cloudflare outputSchemaOperationCount by 1.

Confidence Score: 4/5

Safe to merge. The two-line change in extract.ts is straightforward and the Graph normalization transform is pure and narrowly scoped to octet-stream success responses.

The core logic is correct and well-tested. The only follow-up is a stale comment in plugin.ts that still describes the old undefined return from microsoftGraphKeepPathItem — the behavior is now always a function, which the comment mis-represents for anyone reading it in context.

The comment at line 147 in packages/plugins/microsoft/src/sdk/plugin.ts (unchanged file) now mis-describes the return value of microsoftGraphKeepPathItem for full-graph selections and should be updated.

Important Files Changed

Filename Overview
packages/plugins/openapi/src/sdk/extract.ts Adds wildcard 2XX status-key recognition in extractResponseBody, ranked after exact 2xx codes and before default. Logic is correct and minimal.
packages/plugins/microsoft/src/sdk/graph.ts Adds normalizeMicrosoftGraphContentPathItem and changes microsoftGraphKeepPathItem return type from `KeepPathItem
packages/plugins/microsoft/src/sdk/graph.test.ts New test file with two YAML fixtures mirroring real Graph shapes (2XX keys, $ref error responses, path-level params); four tests cover binary-response detection, report-style normalization, and path-item parameter survival.
packages/plugins/openapi/src/sdk/extract.test.ts New focused extractor tests: verifies 2XX wildcard produces a binaryResponse hint, and that an exact 200 key is preferred over 2XX when both exist.
packages/plugins/openapi/src/sdk/snapshots/real-specs.test.ts.snap Cloudflare baseline bumps outputSchemaOperationCount from 2669 to 2670, reflecting one previously-silent 2XX response now being extracted correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[streamOperationBindingsFromStructure] --> B[keptPathItem per range]
    B --> C{keepPathItem defined?}
    C -- "No (old full-graph)" --> D[rawValue as-is]
    C -- "Yes (all selections now)" --> E[microsoftGraphKeepPathItem]
    E --> F{coversFullGraph?}
    F -- Yes --> G[pathItem unchanged]
    F -- No --> H[filterPathItem\nscope/tag/path filter]
    H --> I{kept?}
    I -- null --> J[skip path-item]
    I -- kept --> K[normalizeMicrosoftGraphContentPathItem]
    G --> K
    K --> L{octet-stream with\nnon-binary schema?}
    L -- Yes --> M[rewrite to type:string format:binary]
    L -- No --> N[leave untouched]
    M --> O[extractResponseBody]
    N --> O
    O --> P{responses key order}
    P --> Q[exact 2xx codes]
    P --> R[wildcard 2XX - new tier]
    P --> S[default]
    Q --> T{schema found?}
    R --> T
    S --> T
    T -- Yes --> U[OperationResponseBody with binaryResponse hint]
    T -- No --> V[undefined]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[streamOperationBindingsFromStructure] --> B[keptPathItem per range]
    B --> C{keepPathItem defined?}
    C -- "No (old full-graph)" --> D[rawValue as-is]
    C -- "Yes (all selections now)" --> E[microsoftGraphKeepPathItem]
    E --> F{coversFullGraph?}
    F -- Yes --> G[pathItem unchanged]
    F -- No --> H[filterPathItem\nscope/tag/path filter]
    H --> I{kept?}
    I -- null --> J[skip path-item]
    I -- kept --> K[normalizeMicrosoftGraphContentPathItem]
    G --> K
    K --> L{octet-stream with\nnon-binary schema?}
    L -- Yes --> M[rewrite to type:string format:binary]
    L -- No --> N[leave untouched]
    M --> O[extractResponseBody]
    N --> O
    O --> P{responses key order}
    P --> Q[exact 2xx codes]
    P --> R[wildcard 2XX - new tier]
    P --> S[default]
    Q --> T{schema found?}
    R --> T
    S --> T
    T -- Yes --> U[OperationResponseBody with binaryResponse hint]
    T -- No --> V[undefined]
Loading

Reviews (1): Last reviewed commit: "fix(openapi): extract success responses ..." | Re-trigger Greptile

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1275

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1275

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1275

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1275

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1275

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1275

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1275

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1275

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1275

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1275

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1275

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1275

executor

npm i https://pkg.pr.new/executor@1275

commit: 0eb1438

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud 0eb1438 Jul 02 2026, 10:22 PM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 0eb1438 Commit Preview URL

Branch Preview URL
Jul 02 2026, 10:21 PM

@RhysSullivan RhysSullivan merged commit dce15d5 into main Jul 3, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant