Tencent/WeKnora · error

create wiki folder: %w

Error message

create wiki folder: %w

What it means

CreateFolder builds the folder entity and persists it via repo.CreateFolder; storage failure is wrapped as 'create wiki folder: %w'. The name has already passed validateFolderName, so failures here are persistence-level: DB errors or path uniqueness conflicts.

Source

Thrown at internal/application/service/wiki_page.go:1542

	path := name
	if parentPath != "" {
		path = parentPath + "/" + name
	}
	now := time.Now()
	folder := &types.WikiFolder{
		ID:              uuid.New().String(),
		TenantID:        tenantID,
		KnowledgeBaseID: kbID,
		ParentID:        parentID,
		Name:            name,
		Path:            path,
		Depth:           depth,
		CreatedAt:       now,
		UpdatedAt:       now,
	}
	if err := s.repo.CreateFolder(ctx, folder); err != nil {
		return nil, fmt.Errorf("create wiki folder: %w", err)
	}
	return folder, nil
}

// FindOrCreateFolderPath resolves a category path to a leaf folder id, creating
// any missing intermediate folders along the way. Concurrency-safe against the
// unique (kb, parent, name) constraint via a re-fetch on create conflict.
func (s *wikiPageService) FindOrCreateFolderPath(
	ctx context.Context, kbID string, tenantID uint64, path []string,
) (string, []string, error) {
	clean := types.CleanWikiCategoryPath(path)
	if len(clean) == 0 {
		return types.WikiFolderRootID, nil, nil
	}
	parentID := types.WikiFolderRootID
	parentPath := ""
	for depth, name := range clean {
		child, err := s.repo.GetChildFolderByName(ctx, kbID, parentID, name)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check the wrapped cause: for duplicate-path errors, reuse the existing folder (or use FindOrCreateFolderPath, which is documented as concurrency-safe).
  2. Retry transient DB failures with backoff.
  3. Verify folders-table migrations and unique constraints are current.
  4. Serialize folder creation per parent in client workflows that bulk-import trees.

Example fix

// before
folder, err := svc.CreateFolder(ctx, kbID, parentID, "Reports")
if err != nil { return err } // fails on concurrent duplicate
// after
folderID, err := svc.FindOrCreateFolderPath(ctx, kbID, []string{"Reports"})
if err != nil { return err } // concurrency-safe
Defensive patterns

Strategy: fallback

Validate before calling

name, err := sanitizeFolderName(requestedName) // strips/rejects separators up front
if err != nil { return err }

Try / catch

folder, err := svc.CreateFolder(ctx, kbID, parentID, name)
if err != nil && strings.Contains(err.Error(), "create wiki folder:") {
    if isDuplicatePath(err) {
        folderID, err = svc.FindOrCreateFolderPath(ctx, kbID, []string{name})
    } else if isTransient(err) {
        time.Sleep(backoff)
        folder, err = svc.CreateFolder(ctx, kbID, parentID, name)
    }
}

Prevention

When it happens

Trigger: CreateFolder where repo.CreateFolder fails — duplicate folder path/name in the same parent, DB connectivity loss, context canceled, or constraint violation on path/depth columns.

Common situations: Two users creating identically named folders in the same parent concurrently (unique path constraint); DB outages during folder-tree imports; schema drift on the folders table after migrations.

Related errors


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