Vikunja Import error "Tried to relate a task with itself"

Hello,

trying to export from one instance and import in another.
api versions used:

  • export: v0.20.1
  • import: unstable v0.20.1+77-682123a9c9
...
2023-01-25T20:16:51.258605156Z: DEBUG	▶ migration/insertFromStructure b15 [creating structure] Created task 110
2023-01-25T20:16:51.271928291Z: DEBUG	▶ migration/insertFromStructure b29 [creating structure] Created task 111
2023-01-25T20:16:51.271990571Z: DEBUG	▶ migration/insertFromStructure b2a [creating structure] Creating 1 related task kinds
2023-01-25T20:16:51.272062772Z: DEBUG	▶ migration/insertFromStructure b2b [creating structure] Creating 2 related tasks for kind subtask
2023-01-25T20:16:51.272109397Z: ERROR	▶ migration/InsertFromStructure b2c [creating structure] Error while creating structure: Tried to relate a task with itself [TaskID: 111, OtherTaskID: 111]
2023-01-25T20:16:51.272138571Z: ERROR	▶ handler/Migrate b2d could not insert data: Tried to relate a task with itself [TaskID: 111, OtherTaskID: 111]

ive looked at task 111, im unable to confirm that its related with itself.

  • 110 has 111 as subtask
  • 111 has 110 as parenttask

Creating 2 related tasks for kind subtask
that doesnt make any sense, 111 only has 1 subtask?

i looked at the code (not! a go dev) and id understand a “relation already exists” error or similar - tasks being created on first sight, so relation already present when processing 111 - but the exception here is different and im unable to make sense of it.

data.json for tasks 110 and 111, ive only stripped the titles.

{
    "assignees": null,
    "attachments": null,
    "bucket_id": 3,
    "comments": null,
    "cover_image_attachment_id": 0,
    "created": "2023-01-08T08:59:41Z",
    "created_by": {
        "created": "2022-12-27T10:29:17Z",
        "id": 1,
        "name": "",
        "updated": "2022-12-30T13:40:43Z",
        "username": "moritz"
    },
    "description": "",
    "done": false,
    "done_at": "0001-01-01T00:00:00Z",
    "due_date": "0001-01-01T00:00:00Z",
    "end_date": "0001-01-01T00:00:00Z",
    "hex_color": "",
    "id": 110,
    "identifier": "-15",
    "index": 15,
    "is_favorite": false,
    "kanban_position": 0,
    "labels": null,
    "list_id": 3,
    "percent_done": 0,
    "position": 0,
    "priority": 0,
    "related_tasks": {
        "subtask": [
            {
                "assignees": null,
                "attachments": null,
                "bucket_id": 3,
                "cover_image_attachment_id": 0,
                "created": "2023-01-08T09:00:27Z",
                "created_by": null,
                "description": "",
                "done": false,
                "done_at": "0001-01-01T00:00:00Z",
                "due_date": "0001-01-01T00:00:00Z",
                "end_date": "0001-01-01T00:00:00Z",
                "hex_color": "",
                "id": 111,
                "identifier": "",
                "index": 16,
                "is_favorite": false,
                "kanban_position": 0,
                "labels": null,
                "list_id": 3,
                "percent_done": 0,
                "position": 0,
                "priority": 0,
                "related_tasks": null,
                "reminder_dates": null,
                "repeat_after": 0,
                "repeat_mode": 0,
                "start_date": "0001-01-01T00:00:00Z",
                "title": "stripped",
                "updated": "2023-01-08T09:05:54Z"
            },
            {
                "assignees": null,
                "attachments": null,
                "bucket_id": 3,
                "cover_image_attachment_id": 0,
                "created": "2023-01-08T09:03:39Z",
                "created_by": null,
                "description": "",
                "done": false,
                "done_at": "0001-01-01T00:00:00Z",
                "due_date": "0001-01-01T00:00:00Z",
                "end_date": "0001-01-01T00:00:00Z",
                "hex_color": "",
                "id": 112,
                "identifier": "",
                "index": 17,
                "is_favorite": false,
                "kanban_position": 0,
                "labels": null,
                "list_id": 3,
                "percent_done": 0,
                "position": 0,
                "priority": 0,
                "related_tasks": null,
                "reminder_dates": null,
                "repeat_after": 0,
                "repeat_mode": 0,
                "start_date": "0001-01-01T00:00:00Z",
                "title": "stripped",
                "updated": "2023-01-08T09:05:54Z"
            }
        ]
    },
    "reminder_dates": null,
    "repeat_after": 0,
    "repeat_mode": 0,
    "start_date": "0001-01-01T00:00:00Z",
    "title": "stripped",
    "updated": "2023-01-08T09:05:54Z"
},
{
    "assignees": null,
    "attachments": null,
    "bucket_id": 3,
    "comments": null,
    "cover_image_attachment_id": 0,
    "created": "2023-01-08T09:00:27Z",
    "created_by": {
        "created": "2022-12-27T10:29:17Z",
        "id": 1,
        "name": "",
        "updated": "2022-12-30T13:40:43Z",
        "username": "moritz"
    },
    "description": "",
    "done": false,
    "done_at": "0001-01-01T00:00:00Z",
    "due_date": "0001-01-01T00:00:00Z",
    "end_date": "0001-01-01T00:00:00Z",
    "hex_color": "",
    "id": 111,
    "identifier": "-16",
    "index": 16,
    "is_favorite": false,
    "kanban_position": 0,
    "labels": null,
    "list_id": 3,
    "percent_done": 0,
    "position": 0,
    "priority": 0,
    "related_tasks": {
        "parenttask": [
            {
                "assignees": null,
                "attachments": null,
                "bucket_id": 3,
                "cover_image_attachment_id": 0,
                "created": "2023-01-08T08:59:41Z",
                "created_by": null,
                "description": "",
                "done": false,
                "done_at": "0001-01-01T00:00:00Z",
                "due_date": "0001-01-01T00:00:00Z",
                "end_date": "0001-01-01T00:00:00Z",
                "hex_color": "",
                "id": 110,
                "identifier": "",
                "index": 15,
                "is_favorite": false,
                "kanban_position": 0,
                "labels": null,
                "list_id": 3,
                "percent_done": 0,
                "position": 0,
                "priority": 0,
                "related_tasks": null,
                "reminder_dates": null,
                "repeat_after": 0,
                "repeat_mode": 0,
                "start_date": "0001-01-01T00:00:00Z",
                "title": "stripped",
                "updated": "2023-01-08T09:05:54Z"
            }
        ]
    },
    "reminder_dates": null,
    "repeat_after": 0,
    "repeat_mode": 0,
    "start_date": "0001-01-01T00:00:00Z",
    "title": "stripped",
    "updated": "2023-01-08T09:05:54Z"
},

Please let me know if you need anything else to debug.

Best
Moritz

It’s reproducible in my case on latest Vikunja version.

Seems to be related to this commit:

// here it sets different IDs for TaskID & OtherTaskID.
// both t.ID and rt.ID are old instance ID + 1 values
taskRel := &models.TaskRelation{
	TaskID:       t.ID,
	OtherTaskID:  rt.ID,
	RelationKind: kind,
}
// here it makes them the same ultimately causing the error ErrRelationTasksCannotBeTheSame
if ttt, exists := tasksByOldID[rt.ID]; exists {
	taskRel.OtherTaskID = ttt.ID
}

I struggle to suggest a fix because I don’t understand what is the expected logic behind re-mapping old task IDs to new ones during the import process.

mhhh that should not happen. It should never even get to that state in the database, actually.

The quickest fix here would be to just ignore the error and keep going, maybe log it.

Imported tasks have new IDs after they are imported. That’s why we can’t just import the relations data as-is, but we need to map these IDs from old to new.

This should now be fixed in 2ead48c1e9, please check with the next unstable build (should be ready for deployment in ~45min, also on try).