Fix README and example patterns that commit truncated uploads or overwrite local files on failure
I maintainer di solito rispondono entro 1 giorno
@ffumero2003 ci sta già lavorando.
Dal 8/11/2026.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
- Tipo di issue
- Documentazione
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- go
- Ambito
- backend, documentation
Direzione di ricerca
Start with the upload and download snippets in README.md, then read b2/writer.go and examples/simple/simple.go for the failure behavior described. Update the examples, memory guidance, and AuthToken prefix and credential notes; the proposed example_test.go examples should compile with go vet ./.... Done when the acceptance criteria pass, including failed uploads leaving no object and failed downloads preserving the existing file.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Context
The README's upload examples call w.Close() on the io.Copy error path. Writer.Close finishes the upload with whatever was written, so when the source is not seekable (a pipe, a network stream, an io.Reader adapter), a source read error stores a truncated object as the newest version and Close returns nil. The README examples read from an *os.File, which takes the seekable path, but the pattern is what users copy for other readers. The download examples truncate the local destination before the first byte arrives, so a mistyped object name empties the local file. The README also omits memory use and uses an AuthToken prefix ("photos") that also matches photos-private/....
Current behavior
At a5e0d13:
- README.md lines 116-122 and 141-147:
if _, err := io.Copy(w, f); err != nil { w.Close(); return err }. - b2/writer.go:649-652: for a non-seekable source,
ReadFromruns a plain copy (b2/reader.go:378-405) and returns the source error without recording it on the writer. - b2/writer.go:717-773:
Closehas no abort path. Cancelling theNewWritercontext beforeCloseis the only way to discard. - Reproduced at a5e0d13 with Go 1.27.3, the README snippets as written and the
x/b2simin-process simulator: a non-seekable source returning 1000 bytes then an error givesio.Copy err=source read failed; w.Close()=nil, and the stored object has 1000 bytes. WithChunkSize5e6 and a source failing after 12e6 bytes (large-file path),Closealso returns nil and 12000000 bytes are stored. - README.md lines 159-173 and examples/simple/simple.go:84-106:
os.Create(dst)runs before the lazy reader (b2/b2.go:763-796) makes its first request. Downloading a missing object over an existing 19-byte file returned404: file not foundand left the file empty. - examples/simple/simple.go:51-111: every error path prints to stdout and returns from
main; a failed upload copy returns without cancelling, leaving an unfinished large file. - README.md lines 126-127 and 151-152 describe
ChunkSizeandConcurrentUploadsbut not that the in-memory buffer is oneChunkSizeper concurrent upload (about 1 GB for 10 uploads by default); neither does theConcurrentUploadsdoc (b2/writer.go:44). - README.md line 231:
bucket.AuthToken(ctx, "photos", time.Hour); lines 234-235 do not say the token is a bearer credential.
Expected behavior
Copy-pasted examples never store partial data, never destroy local files on failure, and describe limits and token scope correctly.
Acceptance criteria
- R1. With the in-memory backend, the documented upload pattern leaves no new object when a non-seekable source fails mid-copy.
- R2. The documented download pattern leaves an existing destination file untouched when the object is missing.
- R3.
examples/simpleexits non-zero for a missing object. - R4. The README states the memory formula;
AuthTokenuses a slash-terminated prefix. - R5.
go vet ./...compilesExamplefunctions for upload, download, list andAuthToken.
In scope
Proposed change
- Cancel the writer context before
Closeon copy errors in both upload snippets, and state in theWriter/Closedocs thatClosecommits what was written. Consider aWriter.AbortorCloseWithError. - Download to a temp file in the destination directory and
os.Renameit after success. - Make
examples/simplewrite errors to stderr, exit non-zero, and cancel on copy failure. - Add the memory formula with a pointer to
UseFileBuffer. - Use
"photos/"in theAuthTokenexample, explain that the prefix is a plain string prefix, and note that the token grants read access to anyone who holds it. - Move snippets into
example_test.goso they are compiled and shown on pkg.go.dev.
Out of scope
- Unrelated work outside the components and behavior described in In scope.
Verification
Run the repository regression checks with live credentials unset:
unset B2_APPLICATION_KEY_ID B2_APPLICATION_KEY B2_ACCOUNT_ID B2_ACCOUNT_KEY
go build ./...
go vet ./...
go test -race -count=1 ./...
- Use the stated failing non-seekable source and missing-download cases. Verify that the documented upload stores no new truncated object and that the local destination remains unchanged.
- Record the example CLI's nonzero exit for a missing object and compile the examples through the originally requested
go vet ./.... - Check the memory formula, slash-terminated token prefix, and bearer-token explanation.
- Expected result: the checks above succeed and the observable outcomes in Acceptance criteria are demonstrated. If a check cannot run, report
Could not run because: ...; if it starts but fails, reportCould not complete because: .... A skipped check is not a pass.
Links
Backblaze/blazer#168 (merged; refreshed the README and corrected the part-size text, but kept these patterns)
- Lingua principale
- Go
- Stelle
- 66
- Fork
- 18
- Merge medio
- 1g 10h
- PR unite (30g)
- 132
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Backblaze/blazer
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
Bucket.Attrs never returns ReplicationConfig: replication configuration is write-onlyForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
test: skip the fuzz non-vacuity guard when replaying a single seedForse già presa @ffumero2003 l’ha presa 5 giorni fa. Apertatesting
Backblaze/blazer#330 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Backblaze/blazer
Issue simili
-
needs-triage typo
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
llm-d-incubation/llm-d-scaling-manager#122 ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue severity: low tech-debt
Difficoltà 2/5 Mezza giornata Idoneità per principianti 75/100
TMHSDigital/subenum#329 ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug] Backend summarize min() / max() panics when a field has no numeric valuesForse già presa @weng5e l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
grafana/grafana-infinity-datasource#1832 ·
I maintainer di solito rispondono entro 1 giorno
-
tech-debt
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
GillMacedo/godebugdiff#13 ·