Tencent/WeKnora · error

bind stored resource: %w

Error message

bind stored resource: %w

What it means

In SaveFile, after a resource is stored and registered, an optional knowledgeID triggers catalog.Bind to link the resource to a knowledge entry as its source file. If Bind fails, DeleteFile is invoked to roll back the stored resource and this wrapped error is returned. The upload is fully undone; the caller must retry the whole operation.

Source

Thrown at internal/application/service/file/resource_catalog.go:104

func (s *resourceCatalogFileService) SaveFile(
	ctx context.Context,
	file *multipart.FileHeader,
	tenantID uint64,
	knowledgeID string,
) (string, error) {
	physical, err := s.inner.SaveFile(ctx, file, tenantID, knowledgeID)
	if err != nil {
		return "", err
	}
	ref, err := s.register(ctx, physical, tenantID, file.Filename, file.Size, false, "")
	if err != nil {
		return "", err
	}
	if knowledgeID != "" {
		if err := s.catalog.Bind(ctx, ref, types.ResourceOwnerKnowledge, knowledgeID, types.ResourceRelationSourceFile); err != nil {
			_ = s.DeleteFile(ctx, ref)
			return "", fmt.Errorf("bind stored resource: %w", err)
		}
	}
	return ref, nil
}

func (s *resourceCatalogFileService) SaveBytes(
	ctx context.Context,
	data []byte,
	tenantID uint64,
	fileName string,
	temp bool,
) (string, error) {
	physical, err := s.inner.SaveBytes(ctx, data, tenantID, fileName, temp)
	if err != nil {
		return "", err
	}
	sum := sha256.Sum256(data)
	return s.register(ctx, physical, tenantID, fileName, int64(len(data)), temp, hex.EncodeToString(sum[:]))

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Verify the knowledgeID exists before calling SaveFile
  2. Inspect the wrapped Bind error for DB/constraint causes
  3. Retry the full SaveFile call — the partial resource was deleted
  4. Remove the knowledgeID argument to store without binding if binding is optional

Example fix

// before
ref, err := svc.SaveFile(ctx, r, knowledgeID)
// after
if knowledgeID != "" {
    if !knowledgeExists(ctx, knowledgeID) { return "", fmt.Errorf("unknown knowledgeID %q", knowledgeID) }
}
ref, err := svc.SaveFile(ctx, r, knowledgeID)
Defensive patterns

Strategy: validation

Validate before calling

if knowledgeID != "" && !catalog.KnowledgeExists(ctx, knowledgeID) {
    return fmt.Errorf("knowledge %q does not exist", knowledgeID)
}

Try / catch

ref, err := svc.SaveFile(ctx, r, knowledgeID)
if err != nil && strings.Contains(err.Error(), "bind stored resource") {
    // stored resource was rolled back; refresh knowledgeID and retry full save
}

Prevention

When it happens

Trigger: Calling SaveFile with a non-empty knowledgeID where the knowledge entry does not exist, was deleted concurrently, or the catalog DB rejects the ownership/relation insert.

Common situations: Stale knowledgeID passed by the client after the knowledge entry was removed, foreign-key constraint on the knowledge table, DB outage during the bind step, duplicate binding attempts.

Related errors


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