AI assistance note: I used AI to explore the Vikunja repository, trace the TickTick import code path, reorder/fix the CSV, and verify that the reordered CSV imported successfully.
The attached file vikunja-ticktick-parent-before-child-minimal.csv reproduces the ordering problem:
- the child task row comes first
parentIdpoints to a parent task row that appears later in the file
- TickTick importer parses
parentIdand turns it into aparenttaskrelation inpkg/modules/migration/ticktick/ticktick.go - Structure insertion creates tasks in CSV row order in
pkg/modules/migration/create_from_structure.go - If a related task does not exist yet, the relation code tries to create it on the fly in
pkg/modules/migration/create_from_structure.go - Task creation rejects empty titles in
pkg/models/tasks.go - The returned error text is
Task title cannot be empty.frompkg/models/error.go
The TickTick importer builds parent-child relations from parentId, but the later insert step still creates tasks sequentially in the same order they appear in the CSV.
When a child row appears before its parent row:
- the child task is created first
- Vikunja sees a
parenttaskrelation to the parent ID - the parent task has not been created yet
- the relation code tries to create a placeholder related task using only the referenced ID
- that placeholder has no title
- task validation fails with
Task title cannot be empty.
So the import becomes sensitive to CSV row order, even though parent-child references should be resolvable independently of row position.
Using a real TickTick export, I found multiple cases where a child row appeared before its parent row. After reordering the CSV so that every parent row appeared before all of its children, the import completed successfully.
- keep the TickTick export format intact
- reorder rows so every parent task appears before its child tasks
- optionally remove rows with empty
Titlevalues if they also exist in the export
Create all tasks first, build a complete old-ID to new-ID map, and only create task relations in a second pass after every task already exists.
That would make TickTick import independent of CSV row order and avoid creating placeholder tasks without titles.