Tencent/WeKnora · error

failed to allocate unique resource handle

Error message

failed to allocate unique resource handle

What it means

Register exhausts its retry loop trying to mint a resource handle that does not already exist for the tenant/location hash. If the repo keeps returning an existing row (or keeps failing uniqueness checks) for every attempt, it gives up with this error. It signals handle-space contention or a deterministic handle generator colliding with stored rows, not a caller input problem.

Source

Thrown at internal/application/service/resource.go:109

			LocationHash:     locationHash,
			Kind:             meta.Kind,
			MimeType:         meta.MimeType,
			OriginalName:     meta.OriginalName,
			Size:             meta.Size,
			ContentHash:      meta.ContentHash,
			Lifecycle:        lifecycle,
		}
		if err := s.repo.Create(ctx, resource); err == nil {
			return types.BuildResourcePath(handle), nil
		} else if !strings.Contains(strings.ToLower(err.Error()), "unique") {
			return "", err
		}
		existing, lookupErr := s.repo.GetByTenantLocation(ctx, tenantID, locationHash)
		if lookupErr == nil && existing != nil {
			return types.BuildResourcePath(existing.Handle), nil
		}
	}
	return "", fmt.Errorf("failed to allocate unique resource handle")
}

func (s *resourceCatalog) Resolve(ctx context.Context, reference string) (*types.StoredResource, error) {
	handle, ok := types.ParseResourcePath(reference)
	if !ok {
		return nil, fmt.Errorf("invalid resource reference")
	}
	resource, err := s.repo.GetByHandle(ctx, handle)
	if err != nil {
		return nil, err
	}
	if resource == nil {
		return nil, fmt.Errorf("resource not found")
	}
	return resource, nil
}

func (s *resourceCatalog) ResolvePath(ctx context.Context, value string) (string, *types.StoredResource, error) {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Pre-check with repo.GetByTenantLocation using the exact same tenantID/locationHash inputs before calling Register to see if the row already exists
  2. Verify the locationHash computation matches what was used when the row was created (version skew)
  3. Retry after a short delay if concurrent Register calls are racing; serialize registration per tenant
  4. Inspect the repo for stuck/duplicate rows that the unique constraint keeps colliding with

Example fix

// before
existing, lookupErr := s.repo.GetByTenantLocation(ctx, tenantID, locationHash)
if lookupErr == nil && existing != nil {
    return types.BuildResourcePath(existing.Handle), nil
}
// after
existing, lookupErr := s.repo.GetByTenantLocation(ctx, tenantID, locationHash)
if lookupErr != nil {
    return "", fmt.Errorf("lookup resource location: %w", lookupErr)
}
if existing != nil {
    return types.BuildResourcePath(existing.Handle), nil
}
Defensive patterns

Strategy: retry

Validate before calling

existing, err := repo.GetByTenantLocation(ctx, tenantID, locationHash)
if err == nil && existing != nil { return types.BuildResourcePath(existing.Handle), nil }

Type guard

func resourceHandleAllocated(handle string, r *types.StoredResource) bool { return r != nil && r.Handle == handle }

Try / catch

path, err := catalog.Register(ctx, tenantID, location)
if err != nil && strings.Contains(err.Error(), "failed to allocate unique resource handle") {
    time.Sleep(50 * time.Millisecond)
    path, err = catalog.Register(ctx, tenantID, location) // bounded retry
}

Prevention

When it happens

Trigger: Calling Register when the tenant+locationHash row already exists but the lookup guard above (GetByTenantLocation) misses it (e.g. eventual-consistent replica, mismatched hash input), or the handle generation loop repeatedly produces handles already claimed in the repo.

Common situations: Re-registering the same physical resource after a partial migration; concurrent Register calls racing on near-identical locations; a changed locationHash algorithm so lookups miss old rows while new handles keep colliding.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/2f87a9d4d157e164. Report an issue: GitHub.