nextcloud / nextcloud/integration_mattermost

Sending files is broken: this.$set is not a function in SendFilesModal (leftover Vue 2 API after Vue 3 migration)

Open Beginner friendly
#151 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
JavaScript
Stars
26
Forks
10
PR merge metrics
No merged PRs in 30d

Description

How to use GitHub

Steps to reproduce
  1. Connect a Mattermost account under Settings → Connected accounts (personal access token).
  2. In the Files app, select a file and choose "Send to Mattermost".
  3. Pick a channel, leave the send type on file upload (not "public link" / "internal link"), then click the send button.
Expected behaviour

The file is uploaded to the selected channel and a message is posted.

Actual behaviour

Nothing happens. The modal stays in its loading state, no error is shown in the UI, and the file is never sent. Nothing is written to nextcloud.log, and the Mattermost server never receives a request — no POST /api/v4/files and no POST /api/v4/posts appear in its debug log.

The JavaScript console shows an uncaught TypeError (full log below).

Root cause

Vue.set / this.$set was removed in Vue 3. The app migrated to Vue 3 in 3.0.0 (#100), but two calls in src/components/SendFilesModal.vue were missed. They are the only two $set occurrences left in src/:

fileStarted(id) {
    this.$set(this.fileStates, id, STATES.IN_PROGRESS)   // line 409
},
fileFinished(id) {
    this.$set(this.fileStates, id, STATES.FINISHED)      // line 412
},

fileStarted() is called synchronously in src/filesplugin.js, before the upload request is issued:

OCA.Mattermost.MattermostSendModalVue.fileStarted(file.id)   // line 266 — throws here
const url = generateUrl('apps/integration_mattermost/sendFile')
axios.post(url, req)                                          // never reached

The TypeError aborts sendFileLoop() before axios.post() runs, which is why no request ever leaves the browser and no server-side log contains anything.

Suggested fix

In Vue 3 fileStates is a reactive proxy, so plain assignment is enough:

fileStarted(id) {
    this.fileStates[id] = STATES.IN_PROGRESS
},
fileFinished(id) {
    this.fileStates[id] = STATES.FINISHED
},

I applied the equivalent change to the shipped bundle (js/integration_mattermost-filesplugin.js) on a production instance and file sending works again, including the per-file progress indicator. Happy to open a PR.

Workaround for other affected users

Sending as a public or internal link still works — sendPublicLinks() and sendInternalLinks() never call fileStarted(). Only the direct file upload path is broken.

The affected code is unchanged on main at the time of writing.

Mattermost integration version: 3.2.0

Server configuration

Web server: Apache

Database: PostgreSQL

PHP version: 8.3.32

Nextcloud version: 33.0.6

Installation method: Nextcloud All-in-One (Docker)

List of activated apps
Enabled:
  - admin_audit: 1.23.0
  - admincockpit: 1.3.2
  - appointments: 2.7.4
  - arbeitszeitcheck: 1.5.9
  - attendance: 1.41.2
  - bruteforcesettings: 6.0.0
  - calendar: 6.5.1
  - call_summary_bot: 3.4.0
  - circles: 33.0.0
  - cloud_federation_api: 1.17.0
  - comments: 1.23.0
  - contacts: 8.7.4
  - contactsinteraction: 1.14.1
  - dashboard: 7.13.0
  - dav: 1.36.0
  - deck: 1.17.4
  - external: 8.0.1
  - federatedfilesharing: 1.23.0
  - files: 2.5.0
  - files_accesscontrol: 4.0.1
  - files_confidential: 5.1.0
  - files_downloadlimit: 5.1.0
  - files_external: 1.25.1
  - files_fulltextsearch: 33.0.0
  - files_pdfviewer: 6.0.0
  - files_reminders: 1.6.0
  - files_sharing: 1.25.2
  - files_trashbin: 1.23.0
  - files_versions: 1.26.0
  - firstrunwizard: 6.0.0
  - fulltextsearch: 33.0.0
  - fulltextsearch_elasticsearch: 33.0.0
  - groupfolders: 21.0.10
  - integration_documenso: 2.1.0
  - integration_giphy: 2.2.1
  - integration_matrix: 1.1.0
  - integration_mattermost: 3.2.0
  - integration_peertube: 2.1.1
  - logreader: 6.0.0
  - lookup_server_connector: 1.21.0
  - mail: 5.10.8
  - nextcloud-aio: 0.8.0
  - nextcloud_announcements: 5.0.0
  - notes: 6.0.1
  - notifications: 6.0.0
  - notify_push: 1.3.5
  - oauth2: 1.21.0
  - ownershiptransfer: 1.5.0
  - password_policy: 5.0.0
  - privacy: 5.0.0
  - profile: 1.2.0
  - provisioning_api: 1.23.0
  - richdocuments: 10.3.0
  - serverinfo: 5.0.0
  - settings: 1.16.0
  - sharebymail: 1.23.0
  - spreed: 23.0.9
  - support: 5.0.0
  - systemtags: 1.23.0
  - tables: 2.2.0
  - talk_matterbridge: 1.34.1026000
  - tasks: 0.18.1
  - text: 7.0.1
  - theming: 2.8.0
  - twofactor_backupcodes: 1.22.0
  - twofactor_nextcloud_notification: 7.0.0
  - twofactor_totp: 15.0.0
  - updatenotification: 1.23.0
  - user_migration: 10.4.0
  - user_status: 1.13.0
  - viewer: 6.0.0
  - webhook_listeners: 1.5.0
  - workflowengine: 2.15.0
Disabled:
  - activity: 6.0.0 (installed 5.0.0)
  - app_api: 33.0.0 (installed 32.0.0)
  - encryption: 2.21.0
  - federation: 1.23.0 (installed 1.22.0)
  - files_archive: 1.2.8 (installed 1.2.8)
  - forms: 5.3.4 (installed 5.3.4)
  - google_synchronization: 4.2.0 (installed 4.2.0)
  - integration_google: 4.4.0 (installed 4.4.0)
  - photos: 6.0.0 (installed 5.0.0)
  - recommendations: 6.0.0 (installed 5.0.0)
  - related_resources: 4.0.0 (installed 3.0.0)
  - survey_client: 5.0.0 (installed 4.0.0)
  - suspicious_login: 11.0.0
  - timesheet: 1.2.0 (installed 1.2.0)
  - user_ldap: 1.24.0
  - weather_status: 1.13.0 (installed 1.12.0)

Nextcloud configuration
{
    "system": {
        "one-click-instance": true,
        "one-click-instance.user-limit": 100,
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "check_data_directory_permissions": false,
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "password": "***REMOVED SENSITIVE VALUE***",
            "port": 6379,
            "timeout": 3,
            "read_timeout": 10
        },
        "overwritehost": "cloud.expatrealestate.de",
        "overwriteprotocol": "https",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "localhost",
            "cloud.expatrealestate.de"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "pgsql",
        "version": "33.0.6.2",
        "overwrite.cli.url": "https:\/\/cloud.expatrealestate.de\/",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbtableprefix": "oc_",
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "maintenance": false,
        "updatechecker": false,
        "loglevel": 2,
        "log_type": "file",
        "logfile": "\/var\/www\/html\/data\/nextcloud.log",
        "log_rotate_size": 10485760,
        "log.condition": {
            "apps": [
                "admin_audit"
            ]
        },
        "preview_max_x": 2048,
        "preview_max_y": 2048,
        "jpeg_quality": 60,
        "enabledPreviewProviders": {
            "1": "OC\\Preview\\Image",
            "2": "OC\\Preview\\MarkDown",
            "3": "OC\\Preview\\MP3",
            "4": "OC\\Preview\\TXT",
            "5": "OC\\Preview\\OpenDocument",
            "6": "OC\\Preview\\Movie",
            "7": "OC\\Preview\\Krita",
            "0": "OC\\Preview\\Imaginary",
            "23": "OC\\Preview\\ImaginaryPDF"
        },
        "enable_previews": true,
        "upgrade.disable-web": true,
        "mail_smtpmode": "smtp",
        "trashbin_retention_obligation": "auto, 30",
        "versions_retention_obligation": "auto, 30",
        "activity_expire_days": 30,
        "simpleSignUpLink.shown": false,
        "share_folder": "\/Shared",
        "one-click-instance.link": "https:\/\/nextcloud.com\/all-in-one\/",
        "upgrade.cli-upgrade-link": "https:\/\/github.com\/nextcloud\/all-in-one\/discussions\/2726",
        "updatedirectory": "\/nc-updater",
        "maintenance_window_start": 100,
        "allow_local_remote_servers": true,
        "davstorage.request_timeout": 3600,
        "documentation_url.server_logs": "https:\/\/github.com\/nextcloud\/all-in-one\/discussions\/5425",
        "htaccess.RewriteBase": "\/",
        "dbpersistent": false,
        "auth.bruteforce.protection.enabled": true,
        "ratelimit.protection.enabled": true,
        "files_external_allow_create_new_local": true,
        "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
        "preview_imaginary_url": "***REMOVED SENSITIVE VALUE***",
        "preview_imaginary_key": "***REMOVED SENSITIVE VALUE***",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "587",
        "mail_sendmailmode": "smtp",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpauth": true,
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "serverid": 445,
        "log_type_audit": "file",
        "logfile_audit": "\/var\/www\/html\/data\/audit.log",
        "onlyoffice": {
            "editors_check_interval": 0,
            "jwt_secret": "***REMOVED SENSITIVE VALUE***",
            "jwt_header": "AuthorizationJwt"
        },
        "update_channel": "stable",
        "DOMAIN": "cloud.expatrealestate.de",
        "AIO_VERSION": "v13.4.0"
    }
}

Browser

Browser name: Firefox

Browser version: 153

Operating system: Archlinux

Browser log
Uncaught TypeError: this.$set is not a function
    fileStarted SendFilesModal.vue:409
    sa filesplugin.js:266
    8588 filesplugin.js:364
    onSendClick SendFilesModal.vue:375
    i runtime-core.esm-bundler.js:199
    s runtime-core.esm-bundler.js:206
    kt runtime-core.esm-bundler.js:4503
    g NcButton-jvoYS2my.mjs:84
    i runtime-core.esm-bundler.js:199
    s runtime-core.esm-bundler.js:206
    n runtime-dom.esm-bundler.js:768
SendFilesModal.vue:409:9

Network log: no request is issued at all when clicking send — the exception aborts the handler
before axios.post('apps/integration_mattermost/sendFile') is reached.

Confirmed in the installed bundle:

$ grep -o "this\.\$set([^)]*)" js/integration_mattermost-filesplugin.js
this.$set(this.fileStates,e,Un.IN_PROGRESS)
this.$set(this.fileStates,e,Un.FINISHED)

Contributor guide

Open the contributing guide

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.

Research direction

Start in src/components/SendFilesModal.vue at fileStarted() and fileFinished(), then trace the call from src/filesplugin.js around line 266. Replace the leftover Vue 2 state updates so file upload reaches axios.post and progress states still update; verify that sending a file posts it to Mattermost without the TypeError.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.