Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[2.x] Extension Manager: queued tasks fail on PostgreSQL (output NOT NULL, command varchar(50))

Open Beginner friendly
#5,116 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
php, sql
Domain
databases

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
  1. Install Flarum 2.x on PostgreSQL and enable the Extension Manager.
  2. Set 'queue' => ['driver' => 'database'] in config.php and enable queued jobs in the Extension Manager settings.
  3. Click "Update" on any extension: the task is never created and the alert above appears (bug 1).
  4. With output made 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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from flarum/framework

All issues in flarum/framework

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.