Skip to content

Commit 687c731

Browse files
filer: drop dead INVALID_PARAMETER_VALUE branch (real conflicts use existing sentinels)
Verified against a real workspace by uploading varied content into pre-existing paths of mismatched node types: every cross-type collision the server can produce surfaces as either: - 400 RESOURCE_ALREADY_EXISTS, or - 409 ALREADY_EXISTS both already caught by errors.Is(err, ErrResourceAlreadyExists) / errors.Is(err, ErrAlreadyExists). The "400 INVALID_PARAMETER_VALUE with 'Requested node type [X] is different from the existing node type [Y]'" shape was hypothesized in the original PR but does not occur in practice on /workspace/import — the branch was dead code. Replace the corresponding unit test with one that pins the actual cross-type collision shape (409 ALREADY_EXISTS with "Node with name X already exists"). Co-authored-by: Isaac
1 parent 1eec0f7 commit 687c731

2 files changed

Lines changed: 15 additions & 21 deletions

File tree

libs/filer/workspace_files_client.go

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"net/http"
1212
"path"
1313
"slices"
14-
"strings"
1514
"time"
1615

1716
"github.com/databricks/databricks-sdk-go"
@@ -209,24 +208,15 @@ func (w *WorkspaceFilesClient) Write(ctx context.Context, name string, reader io
209208
return w.Write(ctx, name, bytes.NewReader(body), sliceWithout(mode, CreateParentDirectories)...)
210209
}
211210

212-
// File already exists at the path. The /workspace/import endpoint reports this
213-
// with two different error_codes depending on whether the conflict was detected
214-
// sequentially (400 RESOURCE_ALREADY_EXISTS) or under concurrent contention
215-
// (409 ALREADY_EXISTS, observed in TestLock). Both are already-exists from the
216-
// caller's perspective.
217-
//
218-
// Existing-object-with-mismatched-node-type (e.g. uploading a regular .py when a
219-
// NOTEBOOK is at the path) surfaces as 400 INVALID_PARAMETER_VALUE with a
220-
// "Requested node type" message — also already-exists from the caller's perspective.
211+
// Path already taken. /workspace/import returns 400 RESOURCE_ALREADY_EXISTS
212+
// for sequential conflicts and 409 ALREADY_EXISTS under concurrent contention
213+
// (observed in TestLock). Same-path collisions where the existing object is a
214+
// different node type (e.g. NOTEBOOK at /a/foo, upload regular content to
215+
// /a/foo) also surface here — verified against a real workspace, the server
216+
// returns one of the two already-exists codes regardless of the type mismatch.
221217
if errors.Is(err, apierr.ErrResourceAlreadyExists) || errors.Is(err, apierr.ErrAlreadyExists) {
222218
return fileAlreadyExistsError{absPath}
223219
}
224-
if errors.Is(err, apierr.ErrInvalidParameterValue) {
225-
var aerr *apierr.APIError
226-
if errors.As(err, &aerr) && strings.Contains(aerr.Message, "Requested node type") {
227-
return fileAlreadyExistsError{absPath}
228-
}
229-
}
230220

231221
// Caller has read access but no write access.
232222
if errors.Is(err, apierr.ErrPermissionDenied) {

libs/filer/workspace_files_client_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,20 @@ func TestWorkspaceFilesClientWriteErrorMapping(t *testing.T) {
187187
expectErrTarget: fileAlreadyExistsError{},
188188
},
189189
{
190-
name: "400 INVALID_PARAMETER_VALUE node type mismatch maps to fileAlreadyExistsError",
190+
// Verified against a real workspace: when an existing NOTEBOOK at /a/foo
191+
// (uploaded earlier as /a/foo.py with the source header) blocks a
192+
// regular-content upload to /a/foo, the server returns 409 ALREADY_EXISTS
193+
// rather than a node-type-specific code.
194+
name: "409 ALREADY_EXISTS for cross-type collision maps to fileAlreadyExistsError",
191195
apiErr: &apierr.APIError{
192-
StatusCode: http.StatusBadRequest,
193-
ErrorCode: "INVALID_PARAMETER_VALUE",
194-
Message: "Requested node type [FILE] is different from the existing node type [NOTEBOOK]",
196+
StatusCode: http.StatusConflict,
197+
ErrorCode: "ALREADY_EXISTS",
198+
Message: "Node with name /dir/foo.py already exists. Please pass overwrite=true to update it.",
195199
},
196200
expectErrTarget: fileAlreadyExistsError{},
197201
},
198202
{
199-
name: "400 INVALID_PARAMETER_VALUE other message passes through",
203+
name: "400 INVALID_PARAMETER_VALUE passes through",
200204
apiErr: &apierr.APIError{
201205
StatusCode: http.StatusBadRequest,
202206
ErrorCode: "INVALID_PARAMETER_VALUE",

0 commit comments

Comments
 (0)