Treat a typed nil blob store, including an unset *S3, as unconfigured and fall back to the local artifact directory.
Keep a constructed S3 or local store unchanged.
Test plan
TestIsNil, TestFinishOpenTypedNilS3UsesLocalArtifacts, and TestFinishOpenKeepsConfiguredBlobStore (SELF, SQLite)
TestOpenPostgresTypedNilS3UsesLocalArtifacts on ci / vet-and-test is skipped locally because AGENT_PG_TEST_DSN is unset; CI runs go test ./... without that DSN too, so the PostgreSQL case is covered later by Dev ci / test-pg
GOWORK=off go vet ./... && GOWORK=off go test -count=1 ./... exit 0 on 46073d30 (SELF)
Why: team/PG startup passes (*S3)(nil) through the Store interface when BLOBSTORE_S3_ENDPOINT is unset, and finishOpen then skips the local fallback. Uploads panic.
Evidence: local vet/test receipt is on Dev task card .task/fix-u7-k4-artifact-upload.md (SELF). GATE is this PR's vet-and-test.
Impact: unset blob stores fall back to local artifacts. Configured object storage is unchanged. Second-instance write traffic stays closed.
Refs: Dev branch fix/u7-k4-artifact-upload; drill result backup-20261012-153441.
## Summary
- Treat a typed nil blob store, including an unset `*S3`, as unconfigured and fall back to the local artifact directory.
- Keep a constructed S3 or local store unchanged.
## Test plan
- [x] `TestIsNil`, `TestFinishOpenTypedNilS3UsesLocalArtifacts`, and `TestFinishOpenKeepsConfiguredBlobStore` (SELF, SQLite)
- [ ] `TestOpenPostgresTypedNilS3UsesLocalArtifacts` on `ci / vet-and-test` is skipped locally because `AGENT_PG_TEST_DSN` is unset; CI runs `go test ./...` without that DSN too, so the PostgreSQL case is covered later by Dev `ci / test-pg`
- [x] `GOWORK=off go vet ./... && GOWORK=off go test -count=1 ./...` exit 0 on `46073d30` (SELF)
Why: team/PG startup passes `(*S3)(nil)` through the `Store` interface when `BLOBSTORE_S3_ENDPOINT` is unset, and `finishOpen` then skips the local fallback. Uploads panic.
Evidence: local vet/test receipt is on Dev task card `.task/fix-u7-k4-artifact-upload.md` (SELF). GATE is this PR's `vet-and-test`.
Impact: unset blob stores fall back to local artifacts. Configured object storage is unchanged. Second-instance write traffic stays closed.
Refs: Dev branch `fix/u7-k4-artifact-upload`; drill result `backup-20261012-153441`.
Why: an unset S3 client passed through the Store interface is not a nil interface, so uploads panic instead of using the local artifact directory.
Evidence: TestIsNil and TestFinishOpenTypedNilS3UsesLocalArtifacts failed before this change and pass after it. The PostgreSQL case skips unless AGENT_PG_TEST_DSN is set.
Impact: only an unset blob store falls back; a constructed S3 or local store is unchanged.
Refs: internal/blobstore/blobstore.go internal/store/store.go
Co-authored-by: Cursor <cursoragent@cursor.com>
weichen
merged commit dc736e339d into main2026-10-13 01:53:03 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
*S3, as unconfigured and fall back to the local artifact directory.Test plan
TestIsNil,TestFinishOpenTypedNilS3UsesLocalArtifacts, andTestFinishOpenKeepsConfiguredBlobStore(SELF, SQLite)TestOpenPostgresTypedNilS3UsesLocalArtifactsonci / vet-and-testis skipped locally becauseAGENT_PG_TEST_DSNis unset; CI runsgo test ./...without that DSN too, so the PostgreSQL case is covered later by Devci / test-pgGOWORK=off go vet ./... && GOWORK=off go test -count=1 ./...exit 0 on46073d30(SELF)Why: team/PG startup passes
(*S3)(nil)through theStoreinterface whenBLOBSTORE_S3_ENDPOINTis unset, andfinishOpenthen skips the local fallback. Uploads panic.Evidence: local vet/test receipt is on Dev task card
.task/fix-u7-k4-artifact-upload.md(SELF). GATE is this PR'svet-and-test.Impact: unset blob stores fall back to local artifacts. Configured object storage is unchanged. Second-instance write traffic stays closed.
Refs: Dev branch
fix/u7-k4-artifact-upload; drill resultbackup-20261012-153441.