juicedata/juicefs · error

delete not existed: %v

Error message

delete not existed: %v

What it means

This error is raised in the 'delete an object' objbench case when deleting an ALREADY-deleted key returns an error. JuiceFS requires that Delete be idempotent: deleting a key that does not exist must succeed (be a no-op), mirroring POSIX unlink semantics. The message wraps whatever error the backend returned for the second Delete.

Source

Thrown at cmd/objbench.go:871

			}
		}
		return nil
	})

	runCase("delete an object", func(blob object.ObjectStorage) error {
		br := []byte("hello")
		if err := blob.Put(ctx, key, bytes.NewReader(br)); err != nil {
			return fmt.Errorf("put object failed: %s", err)
		}
		if err := blob.Delete(ctx, key); err != nil {
			return fmt.Errorf("delete failed: %s", err)
		}
		if _, err := blob.Head(ctx, key); err == nil {
			return fmt.Errorf("expect err is not nil")
		}

		if err := blob.Delete(ctx, key); err != nil {
			return fmt.Errorf("delete not existed: %v", err)
		}
		return nil
	})

	runCase("delete non-exist", func(blob object.ObjectStorage) error {
		if err := blob.Delete(ctx, key); err != nil {
			return fmt.Errorf("deleting a non-existent object returns an error %v", err)
		}
		return nil
	})

	runCase("list objects", func(blob object.ObjectStorage) error {
		br := []byte("hello")
		if err := blob.Put(ctx, key, bytes.NewReader(br)); err != nil {
			return fmt.Errorf("put object failed: %s", err)
		}
		defer blob.Delete(ctx, key) //nolint:errcheck
		if isFileSystem {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. In the ObjectStorage implementation, map not-found delete results to nil (treat 404/NoSuchKey/ENOENT as success) to match S3/POSIX semantics.
  2. Check whether the target is a non-AWS S3-compatible store with stricter delete semantics; fix in the client wrapper.
  3. Verify the vendor/SDK version — some SDKs surface delete errors that upstream S3 does not.
  4. Add a regression test: Delete of a nonexistent key must return nil.
  5. Rerun objbench to confirm the idempotency case passes.

Example fix

// before
func (s *store) Delete(ctx context.Context, key string) error {
    _, err := s.client.DeleteObject(ctx, s.bucket, key)
    return err // returns error when key doesn't exist
}
// after
func (s *store) Delete(ctx context.Context, key string) error {
    _, err := s.client.DeleteObject(ctx, s.bucket, key)
    if isNotFound(err) {
        return nil // deleting a missing key is a no-op
    }
    return err
}
Defensive patterns

Strategy: validation

Validate before calling

// guard: ensure the key was actually removed before relying on idempotent delete
if err := blob.Delete(ctx, key); err != nil {
    if !isNotFound(err) { return err } // treat 404 as success in your own code
}

Try / catch

err := blob.Delete(ctx, key)
if err != nil && isNotFound(err) {
    err = nil // normalize to S3/POSIX idempotent semantics
}

Prevention

When it happens

Trigger: The test deletes the test key, then immediately calls blob.Delete(ctx, key) again; the backend returns an error such as S3 404 NoSuchKey, Swift 404, or a filesystem ENOENT that was not mapped to nil.

Common situations: Implementing a custom ObjectStorage that propagates 404 from S3 instead of treating it as success; a filesystem backend returning ENOENT from os.Remove; some S3-compatible vendors (or gateways) that return errors for deleting a missing key while real S3 does not.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/73a46688f587dfd0. Report an issue: GitHub.