Repository: godotengine/godot (language: cpp)

Issue:
Headless import always emits errors about `!tasks.has(p_task)`
### Tested versions

- Reproducible in: 4.4.rc2
- Reproducible in: 4.4.dev2
- Not reproducible in: 4.4.dev1

### System information

Godot v4.4.rc2 - Windows 11 (build 26100) - Multi-window, 3 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4070 Laptop GPU (NVIDIA; 32.0.15.6636) - AMD Ryzen 9 7940HS w/ Radeon 780M Graphics (16 threads)

### Issue description

(This is a formal issue for what's mentioned [here](https://github.com/godotengine/godot/issues/100900#issuecomment-2567712127), and potentially a duplicate of #100900 itself, but since that one mentions errors at startup I figured it's possibly a different issue.)

When running Godot with `--headless --import` on any project, you're currently met with the following output:

```
ERROR: Do not use progress dialog (task) while flushing the message queue or using call_deferred()!
   at: add_task (editor/progress_dialog.cpp:183)
ERROR: Condition "!tasks.has(p_task)" is true. Returning: canceled
   at: task_step (editor/progress_dialog.cpp:217)
ERROR: Condition "!tasks.has(p_task)" is true. Returning: canceled
   at: task_step (editor/progress_dialog.cpp:217)
ERROR: Condition "!tasks.has(p_task)" is true. Returning: canceled
   at: task_step (editor/progress_dialog.cpp:217)
ERROR: Condition "!tasks.has(p_task)" is true. Returning: canceled
   at: task_step (editor/progress_dialog.cpp:217)
ERROR: Condition "!tasks.has(p_task)" is true. Returning: canceled
   at: task_step (editor/progress_dialog.cpp:217)
ERROR: Condition "!tasks.has(p_task)" is true. Returning: canceled
   at: task_step (editor/progress_dialog.cpp:217)
ERROR: Condition "!tasks.has(p_task)" is true.
   at: end_task (editor/progress_dialog.cpp:240)
```

The import seems to complete successfully despite that, I think.

When bisecting it seems that this is a regression stemming from #93064.

### Steps to reproduce

- Create a new project.
- Run `/path/to/godot --headless --import` in the project folder.
- Note the errors.

### Minimal reproduction project (MRP)

N/A


Discussion / hints:
CC @Hilderin

Fix patch:
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index f1d13123d659..de52afa91cda 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1207,7 +1207,7 @@ void EditorNode::_sources_changed(bool p_exist) {
 		}
 
 		// Start preview thread now that it's safe.
-		if (!singleton->cmdline_export_mode) {
+		if (!singleton->cmdline_mode) {
 			EditorResourcePreview::get_singleton()->start();
 		}
 
@@ -1807,7 +1807,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
 	save_scene_progress->step(TTR("Saving Scene"), 4);
 	_save_scene(p_file, p_idx);
 
-	if (!singleton->cmdline_export_mode) {
+	if (!singleton->cmdline_mode) {
 		EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
 	}
 
@@ -4944,7 +4944,7 @@ bool EditorNode::is_object_of_custom_type(const Object *p_object, const StringNa
 void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
 	if (!singleton) {
 		return;
-	} else if (singleton->cmdline_export_mode) {
+	} else if (singleton->cmdline_mode) {
 		print_line(p_task + ": begin: " + p_label + " steps: " + itos(p_steps));
 	} else if (singleton->progress_dialog) {
 		singleton->progress_dialog->add_task(p_task, p_label, p_steps, p_can_cancel);
@@ -4954,7 +4954,7 @@ void EditorNode::progress_add_task(const String &p_task, const String &p_label,
 bool EditorNode::progress_task_step(const String &p_task, const String &p_state, int p_step, bool p_force_refresh) {
 	if (!singleton) {
 		return false;
-	} else if (singleton->cmdline_export_mode) {
+	} else if (singleton->cmdline_mode) {
 		print_line("\t" + p_task + ": step " + itos(p_step) + ": " + p_state);
 		return false;
 	} else if (singleton->progress_dialog) {
@@ -4967,7 +4967,7 @@ bool EditorNode::progress_task_step(const String &p_task, const String &p_state,
 void EditorNode::progress_end_task(const String &p_task) {
 	if (!singleton) {
 		return;
-	} else if (singleton->cmdline_export_mode) {
+	} else if (singleton->cmdline_mode) {
 		print_line(p_task + ": end");
 	} else if (singleton->progress_dialog) {
 		singleton->progress_dialog->end_task(p_task);
@@ -5220,7 +5220,7 @@ Error EditorNode::export_preset(const String &p_preset, const String &p_path, bo
 	export_defer.android_build_template = p_android_build_template;
 	export_defer.patch = p_patch;
 	export_defer.patches = p_patches;
-	cmdline_export_mode = true;
+	cmdline_mode = true;
 	return OK;
 }
 
@@ -6848,6 +6848,11 @@ EditorNode::EditorNode() {
 	DEV_ASSERT(!singleton);
 	singleton = this;
 
+	// Detecting headless mode, that means the editor is running in command line.
+	if (!DisplayServer::get_singleton()->window_can_draw()) {
+		cmdline_mode = true;
+	}
+
 	Resource::_get_local_scene_func = _resource_get_edited_scene;
 
 	{
diff --git a/editor/editor_node.h b/editor/editor_node.h
index de3af997473a..63788e645f30 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -419,7 +419,7 @@ class EditorNode : public Node {
 	bool script_distraction_free = false;
 
 	bool changing_scene = false;
-	bool cmdline_export_mode = false;
+	bool cmdline_mode = false;
 	bool convert_old = false;
 	bool immediate_dialog_confirmed = false;
 	bool opening_prev = false;


Test patch: