nextcloud/server · error · Error

Failed to load tags for file

Error message

Failed to load tags for file

What it means

Thrown by fetchTagsForFile() when the REPORT-style getDirectoryContents request against /systemtags-relations/files/{fileId} fails. The response is parsed with parseTags after filtering the leading empty entry with a glob, and any DAV failure (401/403/404/5xx, network) is wrapped into this error with the original cause attached.

Source

Thrown at apps/systemtags/src/services/files.ts:31

import { davClient } from './davClient.ts'

/**
 * Fetch all tags for a given file (by id).
 *
 * @param fileId - The id of the file to fetch tags for
 */
export async function fetchTagsForFile(fileId: number): Promise<TagWithId[]> {
	const path = '/systemtags-relations/files/' + fileId
	try {
		const { data: tags } = await davClient.getDirectoryContents(path, {
			data: fetchTagsPayload,
			details: true,
			glob: '/systemtags-relations/files/*/*', // Filter out first empty tag
		}) as ResponseDataDetailed<Required<FileStat>[]>
		return parseTags(tags)
	} catch (error) {
		logger.error(t('systemtags', 'Failed to load tags for file'), { error })
		throw new Error(t('systemtags', 'Failed to load tags for file'), { cause: error })
	}
}

/**
 * Create a tag and apply it to a given file (by id).
 * This returns the id of the newly created tag.
 *
 * @param tag The tag to create
 * @param fileId Id of the file to tag
 */
export async function createTagForFile(tag: Tag, fileId: number): Promise<number> {
	const tagToCreate = formatTag(tag)
	const tagId = await createTag(tagToCreate)
	const tagToSet: ServerTagWithId = {
		...tagToCreate,
		id: tagId,
	}
	await setTagForFile(tagToSet, fileId)

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Inspect (error.cause as WebDAVClientError)?.response?.status: 404 → the fileId is invalid or the file was deleted; 401 → refresh the session
  2. Pass the id of a live file node (from the Files view context), not one captured earlier in the session
  3. If the list is empty where tags are expected, remember invisible/system-internal tags are filtered — verify with an admin account
  4. Check connectivity to /remote.php/dav if the cause is a network error

Example fix

// before
const tags = await fetchTagsForFile(fileId) // throws for deleted files

// after
let tags: TagWithId[]
try {
	tags = await fetchTagsForFile(fileId)
} catch (e) {
	if ((e.cause as WebDAVClientError)?.response?.status === 404) tags = [] // file gone — treat as untagged
	else throw e
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
	const tags = await fetchTagsForFile(fileId)
} catch (error) {
	const status = (error.cause as WebDAVClientError | undefined)?.response?.status
	if (status === 404) {
		// invalid/deleted fileId — show empty tag list or close the sidebar
	} else throw error
}

Prevention

When it happens

Trigger: Requesting tags for a numeric fileId that does not exist (deleted file, id from a stale node), for a file the current user cannot read (403/404), with an expired session (401), or while the DAV endpoint is unreachable. Note only user-visible tags are returned; a file with only invisible tags looks like it has none.

Common situations: Files sidebar opened on a node whose id came from a stale listing; share token without read rights; session expired while the sidebar was open; scripts calling the helper with an arbitrary id instead of a real file id.

Related errors


AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17). Data as JSON: /api/errors/3620baf7e1a84c61. Report an issue: GitHub.