Skip to content

Commit 2bae39b

Browse files
fix an issue with re-reading readable streams
1 parent 4fe7efb commit 2bae39b

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

.github/workflows/harness-image.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ jobs:
6565
if: github.event_name == 'release' || github.ref == 'refs/heads/certification-worker'
6666
needs: build-and-push
6767
runs-on: ubuntu-latest
68+
permissions:
69+
contents: read
6870
steps:
6971
- uses: peter-evans/repository-dispatch@v3
7072
with:

src/sdk/createConductorClient/helpers/fetchWithRetry.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,19 @@ export const retryFetch = async (
113113
? applyTimeout(init, requestTimeoutMs)
114114
: init;
115115

116+
// Request bodies are single-use ReadableStreams. Clone Request inputs
117+
// before each attempt so retries get a fresh body stream.
118+
// this prevents errors like: "Failed to register workflow: Response body object should not be disturbed or locked"
119+
const freshInput = (): Input =>
120+
input instanceof Request ? input.clone() : input;
121+
116122
let lastError: unknown;
117123

118124
// Transport retry loop
119125
for (let transportAttempt = 0; transportAttempt <= maxTransportRetries; transportAttempt++) {
120126
let response: Response;
121127
try {
122-
response = await fetchFn(input, effectiveInit);
128+
response = await fetchFn(freshInput(), effectiveInit);
123129
} catch (error) {
124130
// Timeout/abort errors should NOT be retried
125131
if (isTimeoutError(error)) {
@@ -142,7 +148,7 @@ export const retryFetch = async (
142148
let delay = initialRetryDelay;
143149
for (let rlAttempt = 0; rlAttempt < maxRateLimitRetries; rlAttempt++) {
144150
await new Promise((resolve) => setTimeout(resolve, withJitter(delay)));
145-
rateLimitResponse = await fetchFn(input, effectiveInit);
151+
rateLimitResponse = await fetchFn(freshInput(), effectiveInit);
146152
if (rateLimitResponse.status !== 429) {
147153
return rateLimitResponse;
148154
}
@@ -167,7 +173,7 @@ export const retryFetch = async (
167173
headers: new Headers(effectiveInit?.headers),
168174
};
169175
retryInit.headers.set("X-Authorization", newToken);
170-
return await fetchFn(input, retryInit);
176+
return await fetchFn(freshInput(), retryInit);
171177
}
172178
}
173179

0 commit comments

Comments
 (0)