vxcontrol/pentagi · error

failed to list source directory: %w

Error message

failed to list source directory: %w

What it means

listResourceTree loads the full contents of a directory (the directory row plus all descendants via path LIKE 'root/%') before a directory move or copy. This error wraps the GORM query failure that lists those entries, so the caller knows the tree could not be read and the operation aborts before any mutation.

Source

Thrown at backend/pkg/server/services/resources.go:1131

	}
	if sourceRoot != nil {
		if err := tx.Delete(sourceRoot).Error; err != nil {
			return result, fmt.Errorf("failed to delete source directory %q: %w", sourceRoot.Path, err)
		}
		result.DeletedAfter = append(result.DeletedAfter, convertResource(*sourceRoot))
	}

	return result, nil
}

func listResourceTree(tx *gorm.DB, uid uint64, rootPath string) ([]models.UserResource, error) {
	escapedRoot := resources.EscapeLike(rootPath)
	var entries []models.UserResource
	if err := tx.Where(
		"user_id = ? AND (path = ? OR path LIKE ?)",
		uid, rootPath, escapedRoot+"/%",
	).Order("path ASC").Find(&entries).Error; err != nil {
		return nil, fmt.Errorf("failed to list source directory: %w", err)
	}
	return entries, nil
}

func findResourceByPath(tx *gorm.DB, uid uint64, resourcePath string) (models.UserResource, bool, error) {
	var rec models.UserResource
	err := tx.Where("user_id = ? AND path = ?", uid, resourcePath).First(&rec).Error
	if err == nil {
		return rec, true, nil
	}
	if gorm.IsRecordNotFoundError(err) {
		return models.UserResource{}, false, nil
	}
	return models.UserResource{}, false, err
}

func findResourcesByPaths(tx *gorm.DB, uid uint64, paths []string) ([]models.UserResource, error) {
	if len(paths) == 0 {

View on GitHub (pinned to ea665308ba)

Solutions

  1. Read the wrapped DB error to distinguish timeout vs connection vs permission
  2. Increase statement_timeout or paginate the tree listing for very large directories
  3. Verify DB connectivity/credentials and retry with backoff on transient errors
Defensive patterns

Strategy: retry

Validate before calling

if _, err := db.Raw("SELECT count(*) FROM user_resources WHERE path = ?", rootPath).Rows(); err != nil {
    // connectivity/permission problem: fail fast before the move
}

Try / catch

err := svc.MoveResource(ctx, uid, srcDir, dstDir, false)
if err != nil && strings.Contains(err.Error(), "failed to list source directory") {
    // backoff and retry; check DB health
}

Prevention

When it happens

Trigger: moveDirResource or copyDirResource calls listResourceTree and the SELECT on user_resources fails — DB connection loss, timeout on very large directories, table lock, or permission problem for the DB user.

Common situations: Extremely large directories making the LIKE scan slow enough to hit statement timeouts; database failover/restarts; read-replica lag or misconfigured credentials.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/a874273c6cb82728. Report an issue: GitHub.