{"record":{"id":"8c52d9a69c8071d5","repo":"siyuan-note/siyuan","slug":"cannot-remove-primary-key-field","errorCode":null,"errorMessage":"cannot remove primary key field","messagePattern":"cannot remove primary key field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":7690,"sourceCode":"\tif err != nil {\n\t\treturn &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}\n\t}\n\treturn\n}\n\nfunc RemoveAttributeViewKey(avID, keyID string, removeRelationDest bool) (err error) {\n\tattrView, err := av.ParseAttributeView(avID)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tkey, keyErr := attrView.GetKey(keyID)\n\tif nil != keyErr {\n\t\terr = keyErr\n\t\treturn\n\t}\n\tif av.KeyTypeBlock == key.Type {\n\t\terr = errors.New(\"cannot remove primary key field\")\n\t\treturn\n\t}\n\n\tvar removedKey *av.Key\n\tfor i, keyValues := range attrView.KeyValues {\n\t\tif keyValues.Key.ID == keyID {\n\t\t\tattrView.KeyValues = append(attrView.KeyValues[:i], attrView.KeyValues[i+1:]...)\n\t\t\tremovedKey = keyValues.Key\n\t\t\tattrView.RemoveNewItemTemplateFieldValue(keyID)\n\t\t\tbreak\n\t\t}\n\t}\n\tif nil != removedKey && av.KeyTypeRelation == removedKey.Type && nil != removedKey.Relation {\n\t\tif removedKey.Relation.IsTwoWay {\n\t\t\tvar destAv *av.AttributeView\n\t\t\tif avID == removedKey.Relation.AvID {\n\t\t\t\tdestAv = attrView\n\t\t\t} else {","sourceCodeStart":7672,"sourceCodeEnd":7708,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view.go#L7672-L7708","documentation":"The remove-attribute-view-field operation refuses to delete the primary key (Block-type) field. Every attribute view requires its primary key column, which binds rows to blocks, so it is not removable.","triggerScenarios":"Calling the remove attribute view key/column API with the ID of the column whose type is av.KeyTypeBlock.","commonSituations":"A cleanup script deletes 'unused' columns and includes the primary key; a plugin's delete-column menu does not filter out the primary key; batch removal built from stale column listings.","solutions":["Filter out the KeyTypeBlock column before issuing remove operations","Remove a different, non-primary column","If the whole view is unwanted, delete the attribute view instead of its primary key"],"exampleFix":"// before\nkeys.forEach(k => removeKey(k.id))\n// after\nkeys.filter(k => k.type !== \"block\").forEach(k => removeKey(k.id))","handlingStrategy":"validation","validationCode":"if (key.type === \"block\") throw new Error(\"primary key field cannot be removed\");","typeGuard":"const isRemovable = (key) => key.type !== \"block\";","tryCatchPattern":"try { await removeKey(id); } catch (e) { if (String(e).includes(\"cannot remove primary key\")) return; throw e; }","preventionTips":["Filter out the primary key in delete flows","Mark the primary key immutable in plugin UIs","Fetch fresh key metadata before batch deletions"],"tags":["attribute-view","primary-key","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}