blob/fileblob: fix nil underlying error in IfNotExist precondition check#3734
Open
LeSingh1 wants to merge 3 commits into
Open
blob/fileblob: fix nil underlying error in IfNotExist precondition check#3734LeSingh1 wants to merge 3 commits into
LeSingh1 wants to merge 3 commits into
Conversation
Copy was assigning the source *blobEntry pointer directly to the destination key. Two bugs follow from that. First, the src and dst entries shared the same *driver.Attributes pointer and the same Metadata map. Any in-place mutation of the attributes or metadata through one key would silently corrupt the other. Second, when copying onto an existing key, the destination's original CreateTime was replaced with the source's CreateTime. The reference implementation (fileblob) routes all copies through NewTypedWriter, which preserves the existing CreateTime of any blob being overwritten. memblob did not do the same. The fix deep-copies the Attributes struct and Metadata map for the new destination entry, and carries forward the destination's previous CreateTime when it already exists. Two new unit tests cover both cases: TestCopyPreservesDestinationCreateTime and TestCopyDoesNotAliasEntry.
…rivertest Per review, copying onto an existing key does not preserve the destination's CreateTime consistently across providers, so Copy no longer tries to preserve it; it now only deep-copies the source's attributes and metadata so the two entries are independent. The memblob-specific tests are replaced by a drivertest subtest under testCopy that makes a blob, copies it, mutates the source's attributes through the driver, and verifies the copy is unchanged. It fails for memblob without the fix and passes with it. It is commented out for now because enabling it requires regenerating the record/replay files for providers like S3 and GCS.
In both writer.Close() and writerWithSidecar.Close(), when the IfNotExist precondition is triggered (a blob already exists at the target path), gcerr.New() was called with err==nil as the underlying error. This is because os.Stat() succeeds (err=nil) when the file exists, and that nil value was passed directly to gcerr.New(). Fix by constructing a descriptive error using fmt.Errorf so that the error chain carries meaningful context about which blob triggered the failure. Also fix the message typo 'File already exist' -> 'IfNotExist precondition failed', consistent with how memblob reports this condition.
vangent
reviewed
Jun 20, 2026
vangent
requested changes
Jun 20, 2026
vangent
left a comment
Contributor
There was a problem hiding this comment.
Please rebase to HEAD and force-push, I think that's where the unrelated changes are coming from.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
In both
writer.Close()andwriterWithSidecar.Close(), theIfNotExistprecondition check has two bugs:Nil underlying error: When
os.Statsucceeds (meaning the file exists),errisnil. Thatnilis passed directly togcerr.New()as the underlying error, resulting in an error chain with no meaningful cause.errors.Is/errors.Ascallers get no wrapped context.Typo: The message
"File already exist"is grammatically incorrect and inconsistent with howmemblobreports the same condition.Fix
Replace the
nilunderlying error with a descriptivefmt.Errorf, and update the message to be consistent withmemblob's phrasing:This matches the pattern in
memblobwhereIfNotExistreturns:Testing
The existing
drivertestconformance suite exercisesIfNotExistwrites; this fix ensures the error returned has a non-nil cause when the precondition triggers.