Can I duplicate a project on Studio?

I’d like to duplicate a project on Workflow Studio.

However, when I try to import the project, I get the following error:

Project with tag 1.0.0 already imported.

Could you please guide me on how to proceed with duplicating the project? I want to retain the original and create a new copy for further experimentation.

1 Like

@Paul_Thomas please help

1 Like

Hey Shiv,

  1. Export the project.
  2. Extract the ZIP file, open the project.json file, and update the projectId and projectName. Save the changes.
  3. Compress the folder back into a ZIP file and re-import the project.
1 Like

Hi Team,

As of now, Workflow Studio does not support direct duplication of a project from the UI. If you’re trying to import a project and receive the error:

“Project with tag 1.0.0 already imported.”

…it’s because the system identifies the project based on its internal projectId, and importing a project with the same ID is not allowed.

To help with this, you can use the following custom script that will clone your existing exported project zip, generate a new unique projectId, and allow you to re-import it as a separate project for experimentation—while retaining the original.

import zipfile
import os
import shutil
import uuid
import json
import tempfile
import sys

def update_project_zip(zip_path: str, new_project_name: str, project_description: str) -> str:
    zip_dir = os.path.dirname(zip_path)
    sanitized_name = new_project_name.replace(" ", "_")
    output_zip_path = os.path.join(zip_dir, f"{sanitized_name}.zip")

    temp_dir = tempfile.mkdtemp()
    extracted_folder = os.path.join(temp_dir, "extracted")
    os.makedirs(extracted_folder, exist_ok=True)

    # Step 1: Unzip the input zip file
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(extracted_folder)

    # Step 2: Load project.json and get projectId
    project_json_path = None
    for root, _, files in os.walk(extracted_folder):
        for file in files:
            if file == "project.json":
                project_json_path = os.path.join(root, file)
                break

    if not project_json_path:
        raise FileNotFoundError("project.json not found in the zip archive.")

    with open(project_json_path, "r") as f:
        project_data = json.load(f)

    if "project" not in project_data or "projectId" not in project_data["project"]:
        raise KeyError("projectId not found inside the 'project' object of project.json.")

    old_project_id = project_data["project"]["projectId"]
    new_project_id = str(uuid.uuid4())

    # Step 3: Replace projectId in all files
    for root, _, files in os.walk(extracted_folder):
        for file in files:
            file_path = os.path.join(root, file)
            with open(file_path, "r", encoding="utf-8") as f:
                content = f.read()
            content = content.replace(old_project_id, new_project_id)
            with open(file_path, "w", encoding="utf-8") as f:
                f.write(content)

    # Step 4: Update project.json
    project_data["project"]["projectId"] = new_project_id
    project_data["project"]["name"] = new_project_name
    project_data["project"]["description"] = project_description
    project_data["project"]["enquiry"] = False
    with open(project_json_path, "w") as f:
        json.dump(project_data, f, indent=2)

    # Step 5: Create a new zip file in same location as original
    with zipfile.ZipFile(output_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, _, files in os.walk(extracted_folder):
            for file in files:
                file_path = os.path.join(root, file)
                arcname = os.path.relpath(file_path, extracted_folder)
                zipf.write(file_path, arcname)

    shutil.rmtree(temp_dir)
    return output_zip_path

if __name__ == "__main__":
    if len(sys.argv) == 4:
        project_name = sys.argv[1]
        project_description = sys.argv[2]
        zip_path = sys.argv[3]
    else:
        project_name = input("Enter new project name: ").strip()
        project_description = input("Enter project description: ").strip()
        zip_path = input("Enter path to the project zip file: ").strip()
    
    try:
        output = update_project_zip(zip_path, project_name, project_description)
        print(f"✅ Updated project zip created at: {output}")
    except Exception as e:
        print(f"❌ Error: {e}")

:white_check_mark: How to Use:

You can run the script in two ways:

1. Using Command Line Arguments:

python duplicate_project.py "New Project Name" "Project description here" "/path/to/original_project.zip"

2. Interactive Mode:

Just run the script without arguments, and it will prompt you to enter:

  • New project name
  • Project description
  • Path to the original project zip

Let me know if you face any issues running the script. Hope this helps you continue working without affecting your original project.

Regards,
Shamnad KS

4 Likes