[2.x] Extension Manager: queued tasks fail on PostgreSQL (output NOT NULL, command varchar(50))
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Start in extensions/package-manager/src/Task/Task.php at Task::build(), which saves a pending task without setting the NOT NULL output column; the issue already supplies a candidate fix. Then look at the schema for extension_manager_tasks in extensions/package-manager/migrations (likely the original create-table migration plus a new change migration) to widen command beyond varchar(50). Done means a queued task can be created and the global update command saved on PostgreSQL/SQLite/strict MySQL: verify with php flarum migrate on a strict database and by running the extension manager's task creation path or its existing tests.
Written by the indexing model from the issue text.
Description
Current Behavior
With the queue enabled ('queue' => ['driver' => 'database']) and "queue jobs" turned on in the Extension Manager, two schema problems in extension_manager_tasks break tasks on PostgreSQL. MySQL in non-strict mode silently stores '' and truncates, so they go unnoticed there.
1. Every queued task fails to be created. Task::build() saves a pending task without setting output, but the column is mediumText('output') with no ->nullable(). The admin UI shows "Database query failed. This may be caused by an incompatibility between an extension and your database driver." and the log has:
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "output" of relation "extension_manager_tasks" violates not-null constraint
DETAIL: Failing row contains (1, pending, extension_update, null, fof/links, null, 2026-10-07 01:02:45, null, null, null, null).
2. The Global Update is recorded as failed after Composer has finished. command is string('command', 50), but the global update command is 56 characters (update --prefer-dist --no-dev -a --with-all-dependencies). Composer completes, then Task::end() cannot save the row:
SQLSTATE[22001]: String data, right truncated: 7 ERROR: value too long for type character varying(50)
(SQL: update "extension_manager_tasks" set "status" = failure, "command" = update --prefer-dist --no-dev -a --with-all-dependencies, ...)
The job then stops, so the steps after the update never run: a pending migration from an updated extension stayed unapplied until I ran php flarum migrate by hand.
Steps to Reproduce
- Install Flarum 2.x on PostgreSQL and enable the Extension Manager.
- Set
'queue' => ['driver' => 'database']inconfig.phpand enable queued jobs in the Extension Manager settings. - Click "Update" on any extension: the task is never created and the alert above appears (bug 1).
- With
outputmade nullable, click "Run Global Update": Composer finishes, but the task ends as failed with the varchar(50) error (bug 2).
Expected Behavior
Tasks are created, and the global update is recorded as successful, on PostgreSQL (and SQLite or strict MySQL) just as on non-strict MySQL.
Environment
- Flarum version: core v2.0.0-rc.8, flarum/extension-manager v2.0.0-rc.5 (the same code is unchanged on
2.x) - Website URL: private test site
- Webserver: Caddy with PHP-FPM
- Hosting environment: VPS
- PHP version: 8.5.4
- Database: PostgreSQL 18.6
- Browser: not relevant (server side)
Possible Solution
Set output to an empty string when building a task, and widen command to text (a major update lists every extension, so 255 may also be too short). The patch below applies cleanly to 2.x. I applied the equivalent schema change on our install, and both kinds of task now save.
diff --git a/extensions/package-manager/src/Task/Task.php b/extensions/package-manager/src/Task/Task.php
--- a/extensions/package-manager/src/Task/Task.php
+++ b/extensions/package-manager/src/Task/Task.php
@@ -68,6 +68,8 @@ class Task extends AbstractModel
$task->operation = $operation;
$task->package = $package;
$task->status = static::PENDING;
+ // The output column is NOT NULL; PostgreSQL and SQLite reject a pending task without it.
+ $task->output = '';
$task->created_at = Carbon::now();
$task->save();
diff --git a/extensions/package-manager/migrations/2026_10_07_000000_change_command_column_to_text_in_extension_manager_tasks_table.php b/extensions/package-manager/migrations/2026_10_07_000000_change_command_column_to_text_in_extension_manager_tasks_table.php
new file mode 100644
--- /dev/null
+++ b/extensions/package-manager/migrations/2026_10_07_000000_change_command_column_to_text_in_extension_manager_tasks_table.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of Flarum.
+ *
+ * For detailed copyright and license information, please view the
+ * LICENSE file that was distributed with this source code.
+ */
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Schema\Builder;
+
+return [
+ 'up' => function (Builder $schema) {
+ // Composer commands such as the global update are longer than 50 characters.
+ // MySQL in non-strict mode truncates them; PostgreSQL rejects the row.
+ $schema->table('extension_manager_tasks', function (Blueprint $table) {
+ $table->text('command')->nullable()->change();
+ });
+ },
+ 'down' => function (Builder $schema) {
+ $schema->table('extension_manager_tasks', function (Blueprint $table) {
+ $table->string('command', 50)->nullable()->change();
+ });
+ }
+];
Additional Context
The Extension Manager's Dispatcher silently skips a new request while another task is pending or running, so after bug 1 the UI gives no further feedback on retries.
- Dominant language
- PHP
- Stars
- 6.8k
- Forks
- 887
- Avg merge
- 12h 12m
- Merged PRs (30d)
- 126
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from flarum/framework
-
type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
Maintainers usually reply within 1 day
-
type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
type/bug
Difficulty 1/5 Under an hour Newbie friendliness 75/100
flarum/framework#5231 · 2 comments ·
Maintainers usually reply within 1 day
-
Minimized composer should show title onlyMay be free again @subikshajegadish claimed this 15 days ago, and no pull request is open. Opentype/bug
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
flarum/framework#5076 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
All issues in flarum/framework
Similar issues
-
ObjectMapper
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
symfony/symfony-docs#23390 ·
Maintainers usually reply within 2 days
-
sync-en
Difficulty 1/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
sync-en
Difficulty 1/5 Under an hour Newbie friendliness 83/100
Maintainers usually reply within 3 days
-
Перевод устарел
Difficulty 1/5 Under an hour Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day