nextcloud / nextcloud/context_chat

Initial indexing skips nearly all files of a storage that has more than one mount (getFileSource only tries $mounts[0])

Open
#281 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
PHP
Stars
29
Forks
12
Avg merge
4d 4h
Merged PRs (30d)
5

Description

Which version of Nextcloud are you using?

34.0.4.1 (Nextcloud AIO, PostgreSQL)

Which version of PHP context_chat are you using?

5.4.0

Which version of backend context_chat are you using?

5.4.1

Which browser are you using? In case you are using the phone App, specify the Android or iOS version and device please.

Chrome 152.0.7977.84

Nextcloud deployment method?

AIO

Describe the Bug

On an instance where one storage is mounted by more than one user, the crawler queues the files correctly, but almost none of them ever reach the backend. Every affected item is dropped server-side with File not found or not a file.

The dividing line is not the file type, size or owner — it is the number of mounts the storage has. All storages with exactly one mount indexed fine. The single storage with three mounts contributes almost nothing to the vector database.

Steps to reproduce
  1. Set up a user (userA) whose home storage contains a large number of indexable files.
  2. Share two subfolders of that home storage with a second user (userB). The storage now has three rows in oc_mounts: the owner's LocalHomeMountProvider mount and two Files_Sharing\MountProvider mounts.
  3. Enable Context Chat and let the initial crawl run.
  4. Watch nextcloud.log and the number of indexed documents in the admin settings.
Expected behaviour

Files belonging to a multi-mount storage are indexed like any other file.

Actual behaviour

The queue fills up (queue ids ran past 13000 on this instance) and drains again, but the document count in the vector database stays at roughly the number of files held by the single-mount storages. nextcloud.log fills with warnings while the backend polls /queues/documents:

{"level":2,"app":"context_chat","url":"/ocs/v2.php/apps/context_chat/queues/documents?n=32&format=json",
 "message":"File not found or not a file",
 "userAgent":"ExApp/context_chat_backend/5.4.1 (niquests/3.20.1)",
 "exception":{"File":"/var/www/html/custom_apps/context_chat/lib/Controller/QueueController.php","Line":301}}
Analysis

QueueController::getFileSource() resolves the owning user of a queued file like this (paraphrased from 5.4.0):

  • fetch all mounts for the queue item's storage id via IUserMountCache::getMountsForStorageId()
  • take the first element of that array and use its user id
  • look the file up in that single user's folder via getFirstNodeById()
  • if the lookup returns no File, throw File not found or not a file

There is no iteration and no ordering. When a storage has several mounts, the first array element is effectively arbitrary, and a share mount only exposes the shared subtree. Any file outside that subtree is invisible to the chosen user, so the lookup fails and the item is discarded — even though the storage owner could resolve it without any problem.

Note that StorageService::getUsersForFileId() — which returns all users who can see the file — is already called a few lines further down, after the lookup has succeeded.

Evidence from the affected instance

oc_mounts, grouped by storage:

 storage_id | mounts |      users
------------+--------+-----------------
          3 |      3 | userA, userB
          4 |      1 | userB
          5 |      1 | userC
          6 |      1 | userD
          7 |      1 | userE
          8 |      1 | userF
          9 |      1 | userG
         12 |      1 | userH

The three mounts of storage 3:

 id | storage_id | root_id | user_id | mount_point               | mount_provider_class
----+------------+---------+---------+---------------------------+---------------------------------------
 18 |          3 |   10881 | userB   | /userB/files/<shared dir> | OCA\Files_Sharing\MountProvider
 19 |          3 |   11448 | userB   | /userB/files/<shared dir> | OCA\Files_Sharing\MountProvider
 21 |          3 |     642 | userA   | /userA/                   | OC\Files\Mount\LocalHomeMountProvider

Result: 6252 eligible files, 753 documents in the vector database. The ~750 successful ones come from the single-mount storages; storage 3 — the largest one and the owner's home — contributes virtually nothing. The mount that would always resolve correctly (id 21, the home mount) is the last one in the list.

Backend-side errors are unrelated and expected (encrypted PDFs, empty decoded content, size limit); those files fail after being handed over. The files discussed here never reach the backend at all.

Additional observations
  • Re-running the initial crawl does not help. The crawler itself behaves correctly: it enqueues the files, and the queued rows carry the right file_id and storage_id. The failure is purely in resolving a user during handover.
  • This is consistent with reports that newly created files are indexed while the initial crawl stays incomplete — the FileSystemListenerJob path knows the user from the event and does not have to guess. See also https://help.nextcloud.com/t/context-chat-5-4-0-initial-indexing-remains-incomplete-but-newly-created-files-are-indexed/249446
  • There is currently no occ command to restart the initial crawl, since context_chat:scan was removed in 5.4.0. The crawl above was restarted by unsetting installed_time and re-enabling the app, which makes AppInstallStep schedule a new SchedulerJob.
Possible direction (pseudo code, not a patch)
for each mount in mountsForStorage(storageId):
    node = userFolder(mount.user).getFirstNodeById(fileId)
    if node is a File:
        use it and stop
throw 'File not found or not a file'

Whether the mounts should be ordered (e.g. home mount first), whether the already available getUsersForFileId() is the better source of candidates, and how to avoid the extra lookups on large queues is for you to decide — I did not want to guess at the right design here.

Suggestion

An admin-facing indicator would have helped a lot: the warnings only say File not found or not a file without naming the file id or the user that was tried, so it took a while to see the pattern.

To Reproduce
  1. Set up a user (userA) whose home storage contains a large number of indexable files.
  2. Share two subfolders of that home storage with a second user (userB). The storage now has three rows in oc_mounts: the owner's LocalHomeMountProvider mount and two Files_Sharing\MountProvider mounts.
  3. Enable Context Chat and let the initial crawl run.
  4. Watch nextcloud.log and the number of indexed documents in the admin settings.
PHP logs (Warning these might contain sensitive information)

No response

Ex-App logs (Warning these might contain sensitive information)

No response

Server logs (if applicable)

No response

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 lib/Controller/QueueController.php at getFileSource(), around line 301, and trace getMountsForStorageId() alongside the later getUsersForFileId() call. Reproduce with one storage mounted for multiple users, including shared and home mounts, then verify that files from the multi-mount storage reach the backend without “File not found or not a file” warnings and appear in the document count.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.