fix(bitbucket): render private images in pull request descriptions#28596
Problem
Private Bitbucket Cloud images in pull request descriptions and comments fail to load even when the saved account can read the repository. The renderer requests them without a Bitbucket browser session.
Reproduce by embedding a private repository's Downloads or raw/src image URL in a PR description, then opening Summary → Description in T3 Code. The image should render through the server's existing credentials.
Fixes #19828.
Change
- Recognize Bitbucket Cloud Downloads and repository file URLs, and map web links to the API endpoints that accept tokens.
- Connect Bitbucket to the existing signed media driver API, using saved credentials or the existing environment fallback.
- Keep credentials on the configured API origin. Follow bounded HTTPS redirects to signed storage without forwarding the token, and preserve range requests and streamed bytes.
- Bound response-header waits with the existing API timeout while allowing the media body to stream afterward.
The fix stays in the Bitbucket package. Contracts, UI components, and GitHub handling remain unchanged.
Scope and approval
This addresses the existing Bitbucket image-loading defect documented in #19828 and its maintainer source triage. Credential handling still needs maintainer review; this does not claim prior implementation approval.
Related: #19853 covers private Downloads. This independent implementation covers repository images through raw/src links as well as Downloads and uses the current source-control driver API.
Verification
- Added regression cases failed on unmodified main before the implementation.
- 91 focused tests passed: URL recognition, filename handling, current saved credentials, byte streaming, range forwarding, credential-free storage redirects, unsafe targets, redirect limits, response-header timeout, and existing registry/asset behavior.
- Bitbucket package type checking, targeted lint, formatting, and commit-hook checks passed.
- Manually confirmed private images rendering in a local macOS fork build. The screenshot below comes from that check; identifying content is blurred. The current-main driver port uses the production Bitbucket service with a fake HTTP transport in tests. Live-account rendering of this port and native mobile clients were not rechecked.
Focused test command:
| 1 | vp test run \ |
| 2 | packages/source-control-bitbucket/src/shared/definition.test.ts \ |
| 3 | packages/source-control-bitbucket/src/server/BitbucketApi.test.ts \ |
| 4 | apps/server/src/sourceControl/sourceControlDefinitions.test.ts \ |
| 5 | apps/server/src/assets/AssetAccess.test.ts |
Screenshot
| State | Before | After |
|---|---|---|
| Private Bitbucket image in a PR description | Not captured; reproduction and failure are documented in #19828. | Private Bitbucket image rendered; identifying content blurred |
Implemented with GPT-6.1-Sol using the Codex harness in T3 Code.
Fixes pingdotgg/t3code#19828
Checks
Added 1 commit
- fix(bitbucket): render private images in pull request descriptionsbb5d2f6
Approvability
Verdict: Approved at bb5d2f6
Macroscope's review found this PR approvable — Private Bitbucket images now load through the existing authenticated media pipeline. Restricted source URLs, origin-scoped credentials and existing media-response protections keep the change bounded.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review.
Walkthrough
-
The Bitbucket source-control definition now recognizes supported media URLs and maps them to API URLs. The server exposes a media-fetch operation that applies origin-scoped authentication, validates redirects, and enforces a timeout.
Changes: Bitbucket media fetching
Layer / File(s) Summary Media URL mapping and registration
packages/source-control-bitbucket/src/shared/*The shared handler validates Bitbucket source and download URLs, maps accepted URLs to API endpoints, and sanitizes filenames. The Bitbucket definition registers the handler. Tests cover accepted and rejected URLs and filename handling. Server fetch and driver integration
packages/source-control-bitbucket/src/server/*BitbucketApi.fetchMediaforwards only range headers, applies configured authentication only to the API origin, and validates redirects with a maximum of three hops. The driver exposes the operation. Tests cover credentials, redirects, unrelated URLs, and response-header timeout behavior.Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Sequence Diagram(s)
mermaid1 sequenceDiagram 2 participant Driver as Source-control driver 3 participant Fetch as BitbucketApi.fetchMedia 4 participant API as Configured Bitbucket API origin 5 participant Storage as Redirected storage URL 6 Driver->>Fetch: Send media request 7 Fetch->>API: Fetch with configured authentication and range headers 8 API-->>Fetch: Return redirect location 9 Fetch->>Storage: Fetch without API credentials 10 Storage-->>Fetch: Return media response 11 Fetch-->>Driver: Return response or null Possibly related issues
- pingdotgg/t3code#18757 describes private Forgejo/Gitea images, but this change adds Bitbucket media support only.
- pingdotgg/t3code#11412 describes private GitLab uploads, but this change does not add GitLab support.
Suggested reviewers:
juliusmarminge,only21mil
Merge Risk: External image Minimal · up to bb5d2
-
The reviewed changes are ready to merge after normal checks; no concrete issue remains that requires a fix before merge.
Pre-merge checks: Passed 4
-
Check name Status Explanation Title check Passed The title clearly describes the primary change: fixing private Bitbucket images in pull request descriptions. Linked Issues check Passed Issue #19828requires the server to fetch private Bitbucket Cloud media with Bitbucket credentials, follow the signed-storage redirect, stream the bytes, and limit handling to Bitbucket hosts. The rev…Out of Scope Changes check Passed The changed files are in packages/source-control-bitbucket:
-src/shared/bitbucketMedia.ts(new): URL recognition, API endpoint mapping, and filename derivation.
-src/shared/definition.ts: wire…Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It links the issue and maintainer source triage, describes the changes, and reports focused tests … Full details: Linked Issues check
-
Explanation
Issue
#19828requires the server to fetch private Bitbucket Cloud media with Bitbucket credentials, follow the signed-storage redirect, stream the bytes, and limit handling to Bitbucket hosts. The reviewed head covers each point:- URL mapping:
bitbucketMediaUrlinpackages/source-control-bitbucket/src/shared/bitbucketMedia.tsacceptsbitbucket.org,www.bitbucket.org, andapi.bitbucket.orgonly, over HTTPS without credentials or port. It maps web Downloads and raw/src links, and API Downloads and src links, tohttps://api.bitbucket.org/2.0/repositories/{ws}/{repo}/downloads|src/.... - Registration:
definition.tssetsmediaUrlto this function. The core contract inpackages/source-control-core/src/shared/definition.tssays a client asks the server for media that a host keeps behind a credential, and the host's driver fetches it. This is the generic path that the issue'sgithub-mediadiagnosis describes. - Credentials and redirects: per the summary and the test list in
BitbucketApi.test.ts,BitbucketApi.fetchMediasends saved or environment credentials only to the configured API origin. It does not forward them to redirected storage URLs. It follows at most three bounded HTTPS redirects, rejects credential-bearing or non-HTTPS targets, and forwards onlyrangeandif-range. - Streaming: the response-header wait uses the existing API timeout, and the body streams afterward. Tests cover byte streaming and range forwarding.
Residual uncertainty: this review did not read the renderer dispatch code (
ChatMarkdown) at head. The PR-level claim that the renderer routes Bitbucket images throughmediaUrlrests on the core contract comment and the PR summary. Live-account rendering was not rechecked, and the issue's line references describe an earlier main. The author reports these checks, so they do not block this verdict. - URL mapping:
Full details: Out of Scope Changes check
-
Explanation
The changed files are in
packages/source-control-bitbucket:src/shared/bitbucketMedia.ts(new): URL recognition, API endpoint mapping, and filename derivation.src/shared/definition.ts: wiresbitbucketMediaUrlinto the definition'smediaUrlhandler.src/server/BitbucketApi.ts: adds the scopedfetchMediaoperation.src/server/driver.ts: exposesfetchMediafrommakeInstance.src/shared/definition.test.tsandsrc/server/BitbucketApi.test.ts: regression tests for these behaviors.
Each change maps to the
#19828objectives: URL mapping, credentialed fetch, redirect handling, and streaming. The PR description states that contracts, UI components, and GitHub handling are unchanged. The reviewed evidence does not show unrelated edits. The test command also namesapps/servertest files; the summary lists no change to them, so they only verify existing behavior. No out-of-scope change is demonstrated.
Full details: Description check
-
Explanation
The description includes the required Problem, Change, Scope and approval, and Verification sections. It links the issue and maintainer source triage, describes the changes, and reports focused tests and their limits. It also states that credential handling still needs maintainer review.
-
Finishing Touches
-
Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info
-
External image Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: main
- File: .coderabbit.config.ts
- Commit: b50d8a1
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Advanced
- Run ID:
c73a9986-1190-4c48-a279-073d49485eee
External image Commits
-
Reviewing files that changed from the base of the PR and between b50d8a1b15eed3a75e1e0969765e14c6436d80d7 and bb5d2f6ea5d612411718ceadf293c922722b4f46.
External image Files selected for processing: 6
-
packages/source-control-bitbucket/src/server/BitbucketApi.test.tspackages/source-control-bitbucket/src/server/BitbucketApi.tspackages/source-control-bitbucket/src/server/driver.tspackages/source-control-bitbucket/src/shared/bitbucketMedia.tspackages/source-control-bitbucket/src/shared/definition.test.tspackages/source-control-bitbucket/src/shared/definition.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
External image Recent review info
-
External image Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: main
- File: .coderabbit.config.ts
- Commit: b50d8a1
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Advanced
- Run ID:
c73a9986-1190-4c48-a279-073d49485eee
External image Commits
-
Reviewing files that changed from the base of the PR and between b50d8a1b15eed3a75e1e0969765e14c6436d80d7 and bb5d2f6ea5d612411718ceadf293c922722b4f46.
External image Files selected for processing: 6
-
packages/source-control-bitbucket/src/server/BitbucketApi.test.tspackages/source-control-bitbucket/src/server/BitbucketApi.tspackages/source-control-bitbucket/src/server/driver.tspackages/source-control-bitbucket/src/shared/bitbucketMedia.tspackages/source-control-bitbucket/src/shared/definition.test.tspackages/source-control-bitbucket/src/shared/definition.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
-