nextcloud/server · error · Error
Failed to set tag for file
Error message
Failed to set tag for file
What it means
Thrown by setTagForFile() when the PUT to /systemtags-relations/files/{fileId}/{tagId} fails. This operation attaches an existing tag to a file, and the server enforces both file access and the tag's can-assign permission; failures are wrapped with the original WebDAVClientError as `cause`.
Source
Thrown at apps/systemtags/src/services/files.ts:69
}
/**
* Set a tag for a given file (by id).
*
* @param tag - The tag to set
* @param fileId - The id of the file to set the tag for
*/
export async function setTagForFile(tag: TagWithId | ServerTagWithId, fileId: number): Promise<void> {
const path = '/systemtags-relations/files/' + fileId + '/' + tag.id
const tagToPut = formatTag(tag)
try {
await davClient.customRequest(path, {
method: 'PUT',
data: tagToPut,
})
} catch (error) {
logger.error(t('systemtags', 'Failed to set tag for file'), { error })
throw new Error(t('systemtags', 'Failed to set tag for file'), { cause: error })
}
}
/**
* Delete a tag for a given file (by id).
*
* @param tag - The tag to delete
* @param fileId - The id of the file to delete the tag for
*/
export async function deleteTagForFile(tag: TagWithId, fileId: number): Promise<void> {
const path = '/systemtags-relations/files/' + fileId + '/' + tag.id
try {
await davClient.deleteFile(path)
} catch (error) {
logger.error(t('systemtags', 'Failed to delete tag for file'), { error })
throw new Error(t('systemtags', 'Failed to delete tag for file'), { cause: error })
}
}View on GitHub (pinned to ecdeb153ff)
Solutions
- Pre-check the tag's canAssign/userAssignable flag from fetchTags() and hide or disable non-assignable tags in the picker
- Verify both ids are current (file node from the active view, tag from a fresh fetchTags())
- Inspect error.cause status: 403 → permission, 404 → stale id, 401 → re-login
- For admin-only tags run confirmPassword() before the DAV call
Example fix
// before
await setTagForFile(tag, fileId) // 403 if tag is not user-assignable
// after
if (!tag.canAssign && !isAdmin) {
showError(t('systemtags', 'You are not allowed to assign this tag'))
} else {
await setTagForFile(tag, fileId)
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-check assignability — fetchTags returns oc:can-assign per tag
import { fetchTags, setTagForFile } from './services'
async function assignTagSafely(tag: TagWithId, fileId: number) {
const fresh = (await fetchTags()).find((t) => t.id === tag.id)
if (!fresh) throw new Error('stale tag id')
if (!fresh.userAssignable) {
throw new Error('tag is not assignable by users')
}
await setTagForFile(fresh, fileId)
} Try / catch
try {
await setTagForFile(tag, fileId)
} catch (error) {
const status = (error.cause as WebDAVClientError | undefined)?.response?.status
if (status === 403) { /* can-assign denied */ }
else if (status === 404) { /* file or tag gone — refresh */ }
else throw error
} Prevention
- Filter the tag picker to tags where canAssign/userAssignable is true
- Verify fileId is live before offering tag actions
- Run confirmPassword() when admins assign restricted tags
When it happens
Trigger: PUT failing with 403 when the tag is not user-assignable (oc:user-assignable / oc:can-assign false for this user), 404 when either fileId or tagId no longer exists, 401 after session expiry, or 5xx in maintenance mode.
Common situations: Assigning an admin-only (non-assignable) tag as a regular user; tagging a file that was just deleted or whose share expired; stale tag id from an old tag list; concurrent removal of the tag in another session.
Related errors
- Failed to delete tag for file
- Failed to create tag
- Failed to update tag
- Failed to delete tag
- Failed to load tags for file
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/ab92236b3ef7fba4.
Report an issue: GitHub.