> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ovalbee.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ovalbee.com/_mcp/server.

# Import drag & drop

> Import images and videos into a dataset by dropping them onto the node. Each import adds a new version of the destination dataset, and you choose what happens when a file name is already taken.

## Overview

Imports the images and videos you drop onto the node into an OvalBee dataset, as a new version of that dataset. Each run's files also go to the node's hidden `LAST_RUN` dataset, versioned on every rerun. The node badge counts the files the last run imported and skipped, and opens `LAST_RUN`.

```mermaid
flowchart LR
  n1["Import drag & drop"] --> n2["Dataset"]
```

## Prerequisites

| Requirement | What you need                                                       |
| ----------- | ------------------------------------------------------------------- |
| **Files**   | Image or video files on your local machine that you want to upload. |

## How it works

Pick the destination in **Destination dataset**, or type a new name to create one, and set **On name conflict**.

Drop files or folders onto the node, or click **files** or **folders** on it to pick them, then click **Start upload** in the **Upload files** dialog.

Once the uploads finish, the node runs by itself and imports the supported images and videos into the destination and `LAST_RUN` datasets.

## FAQ

#### Why do I have to set the inputs before dropping the files?

Because the run starts on its own the moment the upload finishes, and it uses whatever the inputs held at that point. Changing the destination or the conflict mode afterwards only affects the next upload, so set them first and drop the files last.

#### How does the node pick the dataset?

From **Destination dataset**. The files land in a new version of that dataset, so the state before the upload stays available as an earlier version, and the `Dataset` output points at the new version. Because each import commits a version under a new ID, the node always resolves the latest version of the selected dataset first — so repeated drops keep stacking on top of each other.

#### What counts as a name conflict?

An uploaded file whose relative path already belongs to an image or video in the destination dataset. **On name conflict** decides what happens:

* **Skip** keeps the existing asset and leaves the uploaded file out of the dataset.
* **Replace** imports the uploaded file and drops the existing asset, together with its annotations, from the new version.
* **Rename** imports the uploaded file next to the existing one under a free name such as `photo_1.jpg`.

#### Does the node import annotation files?

No. This version imports images and videos only. Annotation files and other unsupported types are skipped and aren't included in the import count.

#### What happens if an upload fails?

Each failed file is retried twice. Files that still fail are left out, and the node runs with the rest. When nothing uploads, the node doesn't start.

#### Why does clicking Run fail?

The node imports only what the last drop uploaded, and each run consumes that upload. A run started without a new drop fails and asks you to drop files onto the node. A drop that holds no supported files still runs: the destination gets a new, unchanged version, `LAST_RUN` stays empty, and the badge shows `+0 files`.

#### Does the node keep my folder structure?

Files keep their relative path from the drop as asset metadata, so a nested folder layout is preserved on each imported asset.

## Inputs

**`Destination dataset`** `dataset` — required

Destination dataset the dropped files are added to, or a new name to create one. Each import adds a new version, so what the dataset held before stays available. Key: `DATASET`.

---

**`On name conflict`** `select` — required, default: skip

What happens when a dropped file has the same folder and name as an asset already in the destination dataset. Flow variables aren't accepted. Key: `CONFLICT_MODE`.

Options:

* Skip (`skip`): Keep the existing asset and do not import the uploaded file.
* Replace (`replace`): Import the uploaded file and remove the existing asset, and its annotations, from the dataset.
* Rename (`rename`): Import the uploaded file under a free name such as photo_1.jpg, keeping both.

---

## Outputs

**`Storage Path`** `string`

Internal storage prefix of the staged upload, written by the drag-and-drop widget. Hidden from the flow editor. Key: `STORAGE_PATH`.

---

**`Dataset`** `dataset`

ID of the dataset that received the imported media. Shown as an artifact. Key: `DATASET`.

---

**`Last Run`** `dataset`

Hidden dataset containing media imported during the last run. A rerun writes a new version of it. Shown as an artifact. Key: `LAST_RUN`.

---

**`Last Run Count`** `string`

Short badge showing how many images and videos were imported during the last run. Shown on the node as a badge. Selecting the badge opens `LAST_RUN`. Key: `LAST_RUN_COUNT`.

---

## Widgets

The widget stages dropped files in storage and writes the upload prefix to **Storage Path**. Running the node without dropping anything stops the run with a message asking you to drop files first, because there is no upload to import. A **Storage Path** that is set by hand but is not a valid storage location stops the run as well.

## JSON config

Machine-readable node interface for automation and advanced usage.

#### Show JSON

```json
{
  "name": "Import drag & drop",
  "description": "Import images and videos into a dataset by dropping them onto the node. Each import adds a new version of the destination dataset, and you choose what happens when a file name is already taken.",
  "category": "Import",
  "namespace": "ovalbee",
  "templateKey": "import_ops/import_drag_and_drop",
  "version": "v1",
  "inputs": [
    {
      "key": "DATASET",
      "label": "Destination dataset",
      "type": "dataset",
      "description": "Destination dataset the dropped files are added to, or a new name to create one. Each import adds a new version, so what the dataset held before stays available.",
      "required": true,
      "default": null,
      "visibleWhen": null
    },
    {
      "key": "CONFLICT_MODE",
      "label": "On name conflict",
      "type": "select",
      "description": "What happens when a dropped file has the same folder and name as an asset already in the destination dataset.",
      "required": true,
      "default": "skip",
      "visibleWhen": null,
      "options": {
        "allowVariables": false,
        "options": [
          {
            "label": "Skip",
            "value": "skip",
            "tooltip": "Keep the existing asset and do not import the uploaded file."
          },
          {
            "label": "Replace",
            "value": "replace",
            "tooltip": "Import the uploaded file and remove the existing asset, and its annotations, from the dataset."
          },
          {
            "label": "Rename",
            "value": "rename",
            "tooltip": "Import the uploaded file under a free name such as photo_1.jpg, keeping both."
          }
        ]
      }
    }
  ],
  "outputs": [
    {
      "key": "STORAGE_PATH",
      "label": "Storage Path",
      "type": "string",
      "description": "Internal storage prefix of the staged upload, written by the drag-and-drop widget.",
      "artifact": false,
      "badge": false,
      "badgeOpens": null,
      "hidden": true
    },
    {
      "key": "DATASET",
      "label": "Dataset",
      "type": "dataset",
      "description": "ID of the dataset that received the imported media.",
      "artifact": true,
      "badge": false,
      "badgeOpens": null,
      "hidden": false
    },
    {
      "key": "LAST_RUN",
      "label": "Last Run",
      "type": "dataset",
      "description": "Hidden dataset containing media imported during the last run. A rerun writes a new version of it.",
      "artifact": true,
      "badge": false,
      "badgeOpens": null,
      "hidden": false
    },
    {
      "key": "LAST_RUN_COUNT",
      "label": "Last Run Count",
      "type": "string",
      "description": "Short badge showing how many images and videos were imported during the last run.",
      "artifact": false,
      "badge": true,
      "badgeOpens": "LAST_RUN",
      "hidden": false
    }
  ],
  "widgets": {
    "widget": {
      "id": "import-drag-drop",
      "settings": {}
    }
  }
}
```