{"record":{"id":"b247ee396a07c95c","repo":"siyuan-note/siyuan","slug":"view-ids-is-empty","errorCode":null,"errorMessage":"view IDs is empty","messagePattern":"view IDs is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":6515,"sourceCode":"\tfor _, viewID := range viewIDs {\n\t\tif seen[viewID] {\n\t\t\tcontinue\n\t\t}\n\t\tseen[viewID] = true\n\n\t\tview := attrView.GetView(viewID)\n\t\tif nil == view {\n\t\t\treturn fmt.Errorf(\"view [%s] not found\", viewID)\n\t\t}\n\t\tfield := getAttributeViewField(view, keyID)\n\t\tif nil == field {\n\t\t\treturn fmt.Errorf(\"field [%s] not found in view [%s]\", keyID, viewID)\n\t\t}\n\t\tfields = append(fields, field)\n\t}\n\n\tif 1 > len(fields) {\n\t\treturn errors.New(\"view IDs is empty\")\n\t}\n\tfor _, field := range fields {\n\t\tfield.Hidden = hidden\n\t}\n\treturn\n}\n\nfunc getAttributeViewField(view *av.View, keyID string) (ret *av.BaseField) {\n\tswitch view.LayoutType {\n\tcase av.LayoutTypeTable:\n\t\tif nil == view.Table {\n\t\t\treturn\n\t\t}\n\t\tfor _, column := range view.Table.Columns {\n\t\t\tif column.ID == keyID {\n\t\t\t\treturn column.BaseField\n\t\t\t}\n\t\t}","sourceCodeStart":6497,"sourceCodeEnd":6533,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/attribute_view.go#L6497-L6533","documentation":"Thrown by setAttributeViewFieldsHidden when, after iterating and de-duplicating the viewIDs, no fields were collected (len(fields) < 1). This happens when viewIDs is empty to begin with, or every supplied viewID failed the earlier checks and none accumulated a field — the function refuses a no-op hide/show.","triggerScenarios":"Calling the hide/show operation with an empty viewIDs slice; passing only invalid/duplicate viewIDs that all resolve to nil views or missing fields; an undo replay whose view list was already consumed.","commonSituations":"Frontend 'hide field' button firing before any view was selected; bulk operation built from an empty selection set; defensive guard tripping after upstream filtering removed all entries.","solutions":["Require at least one valid viewID before issuing the hide/show operation on the client.","Validate that viewIDs is non-empty and that each entry resolves to a live view containing the field.","If the user deselects all views, skip the operation rather than sending an empty list."],"exampleFix":"// before\ntransaction([{ action: 'setAttrViewFieldsHidden', avID, keyID, viewIDs: [], hidden: true }])\n// after\nif (viewIDs.length === 0) return\ntransaction([{ action: 'setAttrViewFieldsHidden', avID, keyID, viewIDs, hidden: true }])","handlingStrategy":"validation","validationCode":"if (!Array.isArray(operation.viewIDs) || operation.viewIDs.length === 0) { /* skip the op entirely */ }","typeGuard":"function nonEmptyViewIDs(v: unknown): v is string[] {\n  return Array.isArray(v) && v.every(x => typeof x === 'string') && v.length > 0\n}","tryCatchPattern":null,"preventionTips":["Require at least one selected view before enabling the hide/show control.","Disable the action when the view selection is empty."],"tags":["attribute-view","field-visibility","empty-input","transaction"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}