vxcontrol/pentagi · error

failed to copy resource

Error message

failed to copy resource: %w

What it means

copyFileResource inserts the new UserResource row for the copied file inside the copy transaction. This error wraps the GORM/Postgres failure of that INSERT, meaning the database rejected the copy record (not the file itself). The whole copy transaction is rolled back by the caller.

Solutions

  1. Retry the request; if it is a conflict, list the destination first and either pick a new destination path or pass force=true
  2. Check the DB schema/migrations for the user_resources unique index and column sizes
  3. Verify DB connectivity/health (logs will show the wrapped %w cause)
  4. If caused by concurrent writes, serialize copy operations per user or add retry-on-serialization logic

Example fix

// before
res, err := svc.CopyResource(uid, src, dst, false)
// after
if _, exists := checkDestExists(uid, dst); exists && !allowOverwrite {
    return errors.New("destination exists; pass force to overwrite")
}
res, err := svc.CopyResource(uid, src, dst, allowOverwrite)
Defensive patterns

Strategy: retry

Validate before calling

exists, err := resourceExists(uid, dstPath)
if err != nil { return err }
if exists && !force { return errConflict }

Try / catch

res, err := svc.CopyResource(uid, src, dst, force)
if err != nil {
    var conflict error
    if errors.As(err, &conflict) && errors.Is(conflict, errResourceConflict) {
        // handle overwrite policy
    } else {
        log.WithError(err).Error("copy failed (db insert)") // inspect %w cause
    }
}

Prevention

When it happens

Trigger: DELETE/constraint failure on tx.Create while copying a file: e.g. a unique (user_id, path) collision from a concurrent writer, a NOT NULL/length violation on path or name, or a dead/broken DB connection during the copy API call.

Common situations: Two copy/move requests racing to create the same destination path without force; path exceeding the DB column length after a deep destination directory; DB connection dropped mid-request.

Related errors


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

Appendix: source

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

		if err := tx.Delete(&dest).Error; err != nil {
			return result, fmt.Errorf("failed to delete destination for overwrite: %w", err)
		}
		result.Deleted = append(result.Deleted, convertResource(dest))
		if dest.Hash != "" {
			result.OrphanHashes = append(result.OrphanHashes, dest.Hash)
		}
	}

	newRec := models.UserResource{
		UserID: uid,
		Hash:   src.Hash,
		Name:   path.Base(targetPath),
		Path:   targetPath,
		Size:   src.Size,
		IsDir:  false,
	}
	if err := tx.Create(&newRec).Error; err != nil {
		return result, fmt.Errorf("failed to copy resource: %w", err)
	}

	entry := convertResource(newRec)
	if exists {
		result.Updated = append(result.Updated, entry)
	} else {
		result.Added = append(result.Added, entry)
	}
	return result, nil
}

func (s *ResourceService) copyDirResource(
	tx *gorm.DB,
	uid uint64,
	srcPath, dstPath string,
	force bool,
) (copyResourceResult, error) {
	result := copyResourceResult{}

View on GitHub (pinned to ea665308ba)