Files
hermes-skills/skills/legal/contract-portfolio-analysis/references/nextcloud-file-diagnostics.md
T

3.2 KiB

Nextcloud File Upload Diagnostics

When files appear visible in the Nextcloud web UI but find on the container filesystem returns nothing, use this diagnostic sequence.

Step 1: Check physical filesystem

docker exec <container> find '<nc_data_path>/<dir>' -type f -exec ls -la {} \;

Look for .part and .ocTransferId* files — these are incomplete upload fragments.

Step 2: Rescan

docker exec -u www-data <container> php occ files:scan admin --path='<path>'

Step 3: Check Nextcloud logs

docker exec <container> tail -20 /var/www/html/data/nextcloud.log | python3 -c "
import sys, json
for line in sys.stdin:
    try:
        d = json.loads(line.strip())
        if d.get('level', 0) >= 2:
            print(f'[{d.get(\"time\",\"?\")}] {d.get(\"message\",\"\")[:300]}')
    except: pass
"

Upload failures show: "预期文件大小为 X字节,实际...写入...Y字节"

Step 4: Query MariaDB directly

Find the DB password first:

docker exec <container> grep dbpassword /var/www/html/config/config.php

Then query (use mariadb client, not mysql):

docker exec nextcloud-db-1 mariadb -u nextcloud -p<DB_PASSWORD_FROM_CONFIG> nextcloud -e "
SELECT f.fileid, f.path, f.name, f.size, FROM_UNIXTIME(f.mtime) as modified
FROM oc_filecache f 
WHERE f.path LIKE '%<search_term>%'
ORDER BY f.path;
"

To find children of a directory (by parent fileid):

... -e "SELECT f.fileid, f.parent, f.path, f.name, f.size
FROM oc_filecache f WHERE f.parent IN (<parent_id1>, <parent_id2>);"

Step 5: Clean up fragments

docker exec <container> find '<path>' -name '*.part' -delete
docker exec <container> find '<path>' -name '*.ocTransferId*' -delete

Common root cause

Cloudflare Tunnel (free tier) truncates large file uploads. The Nextcloud chunked upload protocol partially writes, then the connection drops. Repeated retries produce the same result.

Solution: Receive files via alternate channel (WeChat private message → ~/.hermes/cache/documents/) and docker cp into Nextcloud.

Quirk: docker cp'd file present + md5 correct, but files:scan returns 0 and DB row missing (2026-06-17)

After docker cp + chown www-data a new xlsx, php occ files:scan admin --path='小Maggie协作区/.../世茂' returned all-zeros (Folders 0 Files 0) and oc_filecache had no row for the file — so it was invisible in the web UI despite physically existing with a correct md5.

Root cause: files:scan keys off directory mtime; a fresh docker cp into an existing dir doesn't always bump the parent mtime, so the scanner skips it.

Fix (verified):

# 1. touch the parent dir to force an mtime change
docker exec <container> bash -c "touch '/var/www/html/data/admin/files/<REL_PATH>'"
# 2. rescan using the admin/files/ prefixed --path form (not the bare share path)
docker exec -u www-data <container> php occ files:scan --path="admin/files/<REL_PATH>"

This returns Updated N and registers the file. Always verify after upload by querying oc_filecache for the filename (Step 4) — md5 match alone does NOT prove the file is indexed/visible. Don't tell the user "uploaded" until the DB row exists.