{"record":{"id":"6d8ab46396523ced","repo":"siyuan-note/siyuan","slug":"card-cover-source-s-does-not-match-view-s","errorCode":null,"errorMessage":"card cover source [%s] does not match view [%s]","messagePattern":"card cover source \\[(.+?)\\] does not match view \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":2095,"sourceCode":"\t}\n\tif nil == attrView.GetBlockValue(operation.RowID) {\n\t\treturn fmt.Errorf(\"attribute view item [%s] not found\", operation.RowID)\n\t}\n\tview, err := getAttrViewViewByBlockID(attrView, operation.BlockID)\n\tif nil != err {\n\t\treturn\n\t}\n\tif av.LayoutTypeGallery != view.LayoutType && av.LayoutTypeKanban != view.LayoutType {\n\t\treturn av.ErrWrongLayoutType\n\t}\n\tvar source string\n\tif av.LayoutTypeGallery == view.LayoutType {\n\t\tsource = av.CardCoverSource(view.Gallery.CoverFrom, view.Gallery.CoverFromAssetKeyID)\n\t} else {\n\t\tsource = av.CardCoverSource(view.Kanban.CoverFrom, view.Kanban.CoverFromAssetKeyID)\n\t}\n\tif data.Source != source {\n\t\treturn fmt.Errorf(\"card cover source [%s] does not match view [%s]\", data.Source, view.ID)\n\t}\n\tif keyID := av.CardCoverSourceAssetKeyID(data.Source); \"\" != keyID {\n\t\tkey, getErr := attrView.GetKey(keyID)\n\t\tif nil != getErr || nil == key || av.KeyTypeMAsset != key.Type {\n\t\t\treturn fmt.Errorf(\"card cover asset field [%s] not found\", keyID)\n\t\t}\n\t}\n\n\tattrView.SetCardCoverPosition(operation.RowID, data.Source, data.Position)\n\terr = av.SaveAttributeView(attrView)\n\treturn\n}\n\nfunc AppendAttributeViewDetachedBlocksWithValues(avID string, blocksValues [][]*av.Value) (err error) {\n\tattrView, err := av.ParseAttributeView(avID)\n\tif err != nil {\n\t\tlogging.LogErrorf(\"parse attribute view [%s] failed: %s\", avID, err)\n\t\treturn","sourceCodeStart":2077,"sourceCodeEnd":2113,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view.go#L2077-L2113","documentation":"setAttrViewCardCoverPosition recomputes the view's current cover source (from Gallery.CoverFrom or Kanban.CoverFrom) and requires the request's source to match it. If the payload's source differs from the view's configured source, this mismatch error is returned. The position can only be set for the source the view is actually using.","triggerScenarios":"doSetAttrViewCardCoverPosition sent with data.source set to e.g. the asset-field source while the target view's gallery/kanban cover is configured from the uploaded image (or vice versa), or targeting a view whose cover source was changed by another client.","commonSituations":"Clients caching an old cover source; operations sent against the wrong view ID after the user switched views or layouts; concurrent edits where another session changed coverFrom.","solutions":["Read the target view's current coverFrom (gallery or kanban layout) and send that as data.source.","First update the view's cover source configuration to the desired source, then set the position.","Re-fetch the latest attribute view state to resolve stale view IDs or concurrently changed settings."],"exampleFix":"// before\nawait setCardCoverPosition(avID, viewID, rowID, \"field\", pos);\n// after\nconst view = await getAttrView(avID, viewID);\nconst src = view.layoutType === \"gallery\" ? view.gallery.coverFrom : view.kanban.coverFrom;\nawait setCardCoverPosition(avID, viewID, rowID, src, pos);","handlingStrategy":"fallback","validationCode":"const view = await getAttrView(avID, viewID);\nconst currentSource = view.layoutType === \"gallery\" ? view.gallery.coverFrom : view.kanban.coverFrom;\nif (currentSource !== requestedSource) requestedSource = currentSource;","typeGuard":null,"tryCatchPattern":"try { await setCardCoverPosition(...); } catch (e) { if (String(e).includes(\"does not match view\")) await refreshAndApplyCurrentSource(); else throw e; }","preventionTips":["Read the view's live coverFrom before each position update","Change the cover source configuration first, then the position","Avoid caching view configuration across sessions or clients"],"tags":["attribute-view","card-cover","state-mismatch"],"backgroundTag":"invalid-state-transition","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}