siyuan-note/siyuan · error
card cover source [%s] does not match view [%s]
Error message
card cover source [%s] does not match view [%s]
What it means
Thrown by setAttrViewCardCoverPosition when the source in the operation (either 'content' or 'asset:<keyID>') does not equal the source currently configured on the target view (Gallery.CoverFrom/Gallery.CoverFromAssetKeyID or the Kanban equivalents). The view's cover configuration is the source of truth; positions are stored per source per item, so a mismatch is rejected to avoid orphaned positions.
Source
Thrown at kernel/model/attribute_view.go:1949
}
if nil == attrView.GetBlockValue(operation.RowID) {
return fmt.Errorf("attribute view item [%s] not found", operation.RowID)
}
view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
if nil != err {
return
}
if av.LayoutTypeGallery != view.LayoutType && av.LayoutTypeKanban != view.LayoutType {
return av.ErrWrongLayoutType
}
var source string
if av.LayoutTypeGallery == view.LayoutType {
source = av.CardCoverSource(view.Gallery.CoverFrom, view.Gallery.CoverFromAssetKeyID)
} else {
source = av.CardCoverSource(view.Kanban.CoverFrom, view.Kanban.CoverFromAssetKeyID)
}
if data.Source != source {
return fmt.Errorf("card cover source [%s] does not match view [%s]", data.Source, view.ID)
}
if keyID := av.CardCoverSourceAssetKeyID(data.Source); "" != keyID {
key, getErr := attrView.GetKey(keyID)
if nil != getErr || nil == key || av.KeyTypeMAsset != key.Type {
return fmt.Errorf("card cover asset field [%s] not found", keyID)
}
}
attrView.SetCardCoverPosition(operation.RowID, data.Source, data.Position)
err = av.SaveAttributeView(attrView)
return
}
func AppendAttributeViewDetachedBlocksWithValues(avID string, blocksValues [][]*av.Value) (err error) {
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
returnView on GitHub (pinned to 251596fc0d)
Solutions
- Re-read the view's cover configuration (CoverFrom / CoverFromAssetKeyID) on the client after any change and rebuild the source string with av.CardCoverSource before sending position updates.
- Drop queued cover-position operations when the cover source changes, and re-issue them against the new source.
- If the source was intentionally reset, send position: null to clear the old entry instead of an update with the stale source.
Example fix
// before
op.Data = { source: 'asset:20240101000000-old', position }
// after
const view = await getAttrViewView(avID, blockID)
const source = view.gallery.coverFrom === 'asset'
? `asset:${view.gallery.coverFromAssetKeyID}`
: 'content'
op.Data = { source, position } Defensive patterns
Strategy: validation
Validate before calling
const view = await getAttrViewView(avID, blockID)
const cfg = view.layout === 'gallery' ? view.gallery : view.kanban
const expectedSource = cfg.coverFrom === 'content' ? 'content'
: cfg.coverFromAssetKeyID ? `asset:${cfg.coverFromAssetKeyID}` : ''
if (op.data.source !== expectedSource) { /* rebuild op or drop it */ } Try / catch
try { await performTx([op]) } catch (e) {
if (/card cover source .* does not match view/.test(String(e.message ?? e))) { reloadViewCoverConfig(avID, blockID) } else { throw e }
} Prevention
- Re-read CoverFrom/CoverFromAssetKeyID after the user changes the cover source.
- Drop queued position operations when the source changes.
- Send position:null with the old source to clear stale entries.
When it happens
Trigger: User changed the gallery/kanban cover source (e.g. switched from content image to an asset field) and a pending/stale cover-position operation from the old source is still processed; the client sends the wrong source string; concurrent edits from two clients where one reconfigured the cover.
Common situations: Frontend did not re-read the view's CoverFrom/CoverFromAssetKeyID after the user changed the cover config; an undo/redo replay sends an operation with a source that no longer matches; multi-window sync race.
Related errors
- invalid card cover position [%v, %v]
- attribute view item [%s] not found
- card cover asset field [%s] not found
- invalid card aspect ratio preset [%v]
- invalid card aspect ratio [%v]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/6d8ab46396523ced.
Report an issue: GitHub.