Skip to content

Commit 98aa8a7

Browse files
Merge branch 'main' into brendan/browse-csr
2 parents 80ee7fa + 9f42c66 commit 98aa8a7

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3737
- Upgraded `nodemailer` to `^9.0.1`. [#1356](https://github.com/sourcebot-dev/sourcebot/pull/1356)
3838
- Upgraded `@opentelemetry/core` to `^2.8.0`. [#1413](https://github.com/sourcebot-dev/sourcebot/pull/1413)
3939
- [EE] Fixed connector setup dialogs to add scrolling when connector setup content goes out of view.
40+
- Fixed Gitea sync failing with `ERR_STREAM_PREMATURE_CLOSE` by forcing identity encoding on the Gitea API fetch and guarding against null repository responses. [#1405](https://github.com/sourcebot-dev/sourcebot/pull/1405)
4041

4142
## [5.0.4] - 2026-06-18
4243

packages/backend/src/gitea.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ import { measure } from './utils.js';
1212
const logger = createLogger('gitea');
1313
const GITEA_CLOUD_HOSTNAME = "gitea.com";
1414

15+
// Some Gitea instances (particularly when behind certain reverse proxies or with
16+
// response compression enabled) cause `cross-fetch` to fail while reading the
17+
// response body with ERR_STREAM_PREMATURE_CLOSE. Forcing identity encoding and
18+
// closing the connection avoids the premature close.
19+
// @see https://github.com/sourcebot-dev/sourcebot/issues/1404
20+
const customFetch: typeof fetch = (url, options = {}) => {
21+
return fetch(url, {
22+
...options,
23+
headers: {
24+
...(options.headers ?? {}),
25+
'Accept-Encoding': 'identity',
26+
'Connection': 'close',
27+
},
28+
});
29+
};
30+
1531
export const getGiteaReposFromConfig = async (config: GiteaConnectionConfig) => {
1632
const hostname = config.url ?
1733
new URL(config.url).hostname :
@@ -25,7 +41,7 @@ export const getGiteaReposFromConfig = async (config: GiteaConnectionConfig) =>
2541

2642
const api = giteaApi(config.url ?? 'https://gitea.com', {
2743
token: token,
28-
customFetch: fetch,
44+
customFetch,
2945
});
3046

3147
let allRepos: GiteaRepository[] = [];
@@ -49,8 +65,11 @@ export const getGiteaReposFromConfig = async (config: GiteaConnectionConfig) =>
4965
allWarnings = allWarnings.concat(warnings);
5066
}
5167

52-
allRepos = allRepos.filter(repo => repo.full_name !== undefined);
5368
allRepos = allRepos.filter(repo => {
69+
if (repo === null || repo === undefined) {
70+
logger.warn(`Skipping null/undefined repository returned by the Gitea API`);
71+
return false;
72+
}
5473
if (repo.full_name === undefined) {
5574
logger.warn(`Repository with undefined full_name found: repoId=${repo.id}`);
5675
return false;
@@ -208,6 +227,10 @@ const getRepos = async <T>(repoList: string[], api: Api<T>) => {
208227
api.repos.repoGet(owner, repoName),
209228
);
210229

230+
if (response.error || !response.data) {
231+
throw response.error ?? new Error(`Received empty response body while fetching repository ${repo}`);
232+
}
233+
211234
logger.debug(`Found repo ${repo} in ${durationMs}ms.`);
212235
return {
213236
type: 'valid' as const,

0 commit comments

Comments
 (0)