Tencent/WeKnora · error

resource release requires owner type and id

Error message

resource release requires owner type and id

What it means

Release mirrors Bind's requirement: it needs ownerType and ownerID to identify whose bindings to remove. Blank owner fields abort with this error before any lookup. Note the deliberate contrast — an unparseable reference returns (‑1, nil) for legacy paths, but a blank owner is always a hard error.

Source

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

		ResourceID: resource.ID,
		TenantID:   resource.TenantID,
		OwnerType:  ownerType,
		OwnerID:    ownerID,
		Relation:   relation,
	})
}

// Release implements interfaces.ResourceCatalog.
//
// Unbinding and counting are deliberately not a single transaction. A racing
// bind that lands between them makes the count too high, which keeps a live
// file — the safe direction. The opposite ordering could delete bytes another
// owner had just claimed.
func (s *resourceCatalog) Release(
	ctx context.Context, reference, ownerType, ownerID string,
) (int64, error) {
	if strings.TrimSpace(ownerType) == "" || strings.TrimSpace(ownerID) == "" {
		return -1, fmt.Errorf("resource release requires owner type and id")
	}
	if _, ok := types.ParseResourcePath(reference); !ok {
		// A raw provider path predates the catalog and has no bindings to
		// account for; the caller keeps its previous delete behaviour.
		return -1, nil
	}
	resource, err := s.Resolve(ctx, reference)
	if err != nil {
		return -1, err
	}
	if err := s.repo.DeleteBinding(ctx, resource.ID, ownerType, ownerID); err != nil {
		return -1, err
	}
	return s.repo.CountBindings(ctx, resource.ID)
}

func (s *resourceCatalog) MarkDeleted(ctx context.Context, reference string) error {
	resource, err := s.Resolve(ctx, reference)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Pass the same ownerType/ownerID used in the original Bind call
  2. Validate owner fields before invoking Release
  3. If ownership is unknown, resolve it first via bindings lookup instead of releasing with blanks
  4. Return a 400-style validation error to callers who omit owner metadata

Example fix

// before
removed, err := catalog.Release(ctx, ref, owner.Type, owner.ID)
// after
if strings.TrimSpace(owner.Type) == "" || strings.TrimSpace(owner.ID) == "" {
    return fmt.Errorf("cannot release without owner identity")
}
removed, err := catalog.Release(ctx, ref, owner.Type, owner.ID)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(ownerType) == "" || strings.TrimSpace(ownerID) == "" {
    return errors.New("owner identity required for release")
}

Type guard

func releaseable(ref, ownerType, ownerID string) bool {
    _, ok := types.ParseResourcePath(ref)
    return ok && strings.TrimSpace(ownerType) != "" && strings.TrimSpace(ownerID) != ""
}

Try / catch

n, err := catalog.Release(ctx, ref, ownerType, ownerID)
if err != nil && strings.Contains(err.Error(), "requires owner type and id") {
    return ErrMissingOwner
}

Prevention

When it happens

Trigger: Calling Release with empty or whitespace ownerType/ownerID, typically when the owning entity was never resolved or the owner struct is zero-valued.

Common situations: Cleanup jobs running without owner context; API handlers dropping owner fields during deserialization; tests calling Release with placeholder empty values.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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