nextcloud/server · warning · Error

Tag not found

Error message

Tag not found

What it means

Thrown by getContents() in apps/systemtags/src/services/systemtags.ts, the virtual 'Tags' files view. It fetches all tags once (fetchTags, filtered to userVisible), parses a numeric tag id from the first path segment, and throws this error when no cached tag matches that id. It is a pure client-side cache miss, not a server response — the DAV REPORT for contents only runs after the lookup succeeds.

Source

Thrown at apps/systemtags/src/services/systemtags.ts:86

				id: 0,
				source: `${getRemoteURL()}${rootPath}`,
				owner: getCurrentUser()?.uid as string,
				root: rootPath,
				permissions: Permission.NONE,
			}),
			contents: tagsCache.map(tagToNode),
		}
	}

	const tagIdStr = path.split('/', 2)[1]
	if (!tagIdStr || isNaN(parseInt(tagIdStr))) {
		throw new Error('Invalid tag ID')
	}

	const tagId = parseInt(tagIdStr)
	const tag = tagsCache.find((tag) => tag.id === tagId)
	if (!tag) {
		throw new Error('Tag not found')
	}

	const folder = tagToNode(tag)
	const contentsResponse = await client.getDirectoryContents(getRootPath(), {
		details: true,
		// Only filter favorites if we're at the root
		data: formatReportPayload(tagId),
		headers: {
			// Patched in WebdavClient.ts
			method: 'REPORT',
		},
	}) as ResponseDataDetailed<FileStat[]>

	return {
		folder,
		contents: contentsResponse.data.map((stat) => resultToNode(stat)),
	}
}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Handle this error in the files-view router by navigating back to '/' and refetching, instead of leaving the user on a dead route
  2. Refetch the tag list before resolving a deep link: fetchTags() and verify the id is present and userVisible
  3. Filter out non-userVisible tags when building clickable entries, so users can never navigate into ids that cannot resolve
  4. If the tag is expected to exist, check whether it was deleted by another session/admin before assuming a bug
Defensive patterns

Strategy: validation

Validate before calling

// Verify the route target against a fresh tag list before navigating
import { fetchTags } from './services/api.ts'

async function canEnterTagFolder(tagId: number): Promise<boolean> {
	const tags = await fetchTags()
	return tags.some((t) => t.id === tagId && t.userVisible)
}

Try / catch

try {
	const { folder, contents } = await getContents(`/${tagId}`)
} catch (error) {
	if (error instanceof Error && error.message === 'Tag not found') {
		// navigate back to '/' and refetch instead of rendering a dead view
	} else throw error
}

Prevention

When it happens

Trigger: Navigating the tags virtual folder to '/{tagId}' where the id is not in the freshly fetched, userVisible-filtered cache: the tag was deleted in another session, the tag exists but is not user-visible (filtered out at line 63), the path segment is a valid number but refers to a tag created after this list call, or the view was entered with a deep link to a stale id.

Common situations: Deep link or bookmark to /tags/{id} after the tag was removed; user-invisible tags (admin/system tags) addressed by id; race between listing the root and entering a tag; tests navigating the virtual root with hardcoded ids.

Related errors


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