🐛 Bug Report: Function and webhook events reject `tablesdb.*.tables.*.rows.*.upsert` ("Event is not valid") · Issue #14653 · appwrite/appwrite · GitHub
Skip to content

🐛 Bug Report: Function and webhook events reject tablesdb.*.tables.*.rows.*.upsert ("Event is not valid") #14653

Open

Description

@JoshiJoshiJoshi

👟 Reproduction steps

  1. Self-hosted Appwrite 2.5.0, a project, a server API key with functions.write.

  2. Create a function that subscribes to the row upsert event:

    curl -X POST "$ENDPOINT/functions" \
      -H "x-appwrite-project: $PROJECT" -H "x-appwrite-key: $KEY" -H "content-type: application/json" \
      -d '{"functionId":"upsert-probe","name":"upsert-probe","runtime":"node-22",
           "events":["tablesdb.*.tables.*.rows.*.upsert"]}'
  3. Repeat with other spellings of the same event.

👍 Expected behavior

The function is created. upsert is a documented row event
(app/config/events.php,
platform events docs), and Appwrite emits it: a function subscribed to
tablesdb.<db>.tables.<table>.rows.* receives tablesdb.<db>.tables.<table>.rows.<id>.upsert for
single and bulk upserts.

👎 Actual Behavior

400 general_argument_invalid: "Invalid events param: Value must a valid array no longer than 100
items and Event is not valid."

Subscription Result
tablesdb.<db>.tables.<t>.rows.*.create / .update / .delete accepted
tablesdb.<db>.tables.<t>.rows.*.upsert rejected
tablesdb.*.tables.*.rows.*.upsert rejected
databases.<db>.collections.<c>.documents.*.upsert rejected
tablesdb.<db>.tables.<t>.rows.* (no action) accepted, upsert events arrive

Cause: for a pattern with three resource levels (type.id.subType.id.subSubType.id.action),
Event::isValid()
takes the action from $parts[6] but looks it up one level too high:

if ($subType) {
    if ($action && !\array_key_exists($action, $events[$type][$subType])) {   // $events['tablesdb']['tables']
        return false;
    }

create, update and delete pass only because the table level has actions with the same names.
upsert exists only under rows, so every row upsert subscription is refused. The same
validator is used for webhooks (Webhooks/Http/Webhooks/Create.php, Update.php).

Side effect: one rejected entry fails the whole function update, so appwrite push functions
also does not deploy the code, and the previous deployment keeps running.

Suggested fix: when $hasSubSubResource, check the action against
$events[$type][$subType][$subSubType] (and the attribute part likewise).

🎲 Appwrite version

Different version (specify in environment)

💻 Operating system

Linux

🧱 Your Environment

Appwrite 2.5.0, self-hosted with Docker Compose (Postgres). Reproduced on a fresh installation
without modifications and on a production cluster.

👀 Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

Related: #10317 (added upsert to the events config)

🏢 Have you read the Code of Conduct?

Activity

  1. added
    api / realtimeFixes and upgrades for the Appwrite Realtime API.
    product / databasesFixes and upgrades for the Appwrite Database.
    product / functionsFixes and upgrades for the Appwrite Functions.
    product / messagingFixes and upgrades for the Appwrite Messaging.
    product / self-hostedIssues only found when self-hosting Appwrite
    product / sitesFixes and upgrades for Appwrite Sites.
    product / vcsFixes and upgrades for the Appwrite VCS.
    on Oct 19, 2026
  2. drakeo338 commented on Oct 19, 2026

    @drakeo338

    Hi, I'd like to be assigned to this one. I've reproduced it and have a fix with a test ready to open as a PR shortly.

  3. drakeo338 commented on Oct 21, 2026

    @drakeo338

    Releasing this one: I won't be opening the PR after all, so anyone is welcome to pick it up.

  4. callmegautam commented on Oct 21, 2026

    @callmegautam

    Hi, since this one was released, I'd like to pick it up. I have a fix with a unit regression test: for 7-part patterns, Event::isValid() now checks the action against the sub-sub resource level (rows / documents) and not the parent (tables / collections), so ...rows.*.upsert is accepted and unknown row actions are still rejected. I've opened the fix in #14742.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    api / realtimeFixes and upgrades for the Appwrite Realtime API.product / databasesFixes and upgrades for the Appwrite Database.product / functionsFixes and upgrades for the Appwrite Functions.product / messagingFixes and upgrades for the Appwrite Messaging.product / self-hostedIssues only found when self-hosting Appwriteproduct / sitesFixes and upgrades for Appwrite Sites.product / vcsFixes and upgrades for the Appwrite VCS.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions