{"record":{"id":"9dec1883f1a397c5","repo":"siyuan-note/siyuan","slug":"document-not-found-or-has-no-headings","errorCode":null,"errorMessage":"document not found or has no headings","messagePattern":"document not found or has no headings","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/cli/cmd/outline.go","lineNumber":47,"sourceCode":"var outlineCmd = &cobra.Command{\n\tUse:   \"outline\",\n\tShort: \"Document outline (heading tree)\",\n}\n\nvar outlineGetCmd = &cobra.Command{\n\tUse:   \"get --id <id>\",\n\tShort: \"Get document outline\",\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tid, _ := cmd.Flags().GetString(\"id\")\n\t\tif id == \"\" {\n\t\t\treturn fmt.Errorf(\"--id is required\")\n\t\t}\n\t\tpaths, err := model.Outline(id, false)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(paths) == 0 {\n\t\t\treturn fmt.Errorf(\"document not found or has no headings\")\n\t\t}\n\t\tswitch outputFormat {\n\t\tcase \"json\":\n\t\t\tdata, _ := json.MarshalIndent(paths, \"\", \"  \")\n\t\t\tfmt.Println(string(data))\n\t\tdefault:\n\t\t\tvar sb strings.Builder\n\t\t\tsb.WriteString(fmt.Sprintf(\"Document outline (%d headings):\\n\\n\", countOutlineHeadings(paths)))\n\t\t\tfor _, p := range paths {\n\t\t\t\twriteOutlinePath(&sb, p, 0)\n\t\t\t}\n\t\t\tfmt.Print(sb.String())\n\t\t}\n\t\treturn nil\n\t},\n}\n\nfunc countOutlineHeadings(paths []*model.Path) int {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/cli/cmd/outline.go#L29-L65","documentation":"Returned by `outline get` when model.Outline(id, false) returns a non-nil error-free but empty paths slice. An empty result means either the ID resolves to no document or the document has no heading blocks to build a tree from.","triggerScenarios":"Calling `outline get --id <id>` where id points to a non-existent document, a non-document block, or a document that contains no heading nodes; len(paths) == 0.","commonSituations":"Using a block ID instead of a document root ID, a document written entirely with paragraphs/lists (no headings), or a deleted/moved document whose ID is stale.","solutions":["Confirm the ID is a document root ID (not a child block) via `block get` or the editor.","Ensure the target document actually contains heading blocks.","Verify the document still exists in the current workspace."],"exampleFix":"# before\nsiyuan outline get --id 202406011200-paragraphblock\ngot: document not found or has no headings\n# after (use the document root id, and ensure it has headings)\nsiyuan outline get --id 202406011200-docroot","handlingStrategy":"type-guard","validationCode":"# verify the id is a real document with headings before calling outline\nid=\"$DOC_ID\"\nsiyuan block get --id \"$id\" >/dev/null 2>&1 || { echo \"block missing\"; exit 1; }","typeGuard":"// Distinguish 'no such document' from 'document has no headings' by\n// checking the block exists and is a document root before outlining.\nfunc isDocumentRoot(id string) bool {\n    b, err := model.GetBlock(id)\n    if err != nil || b == nil {\n        return false\n    }\n    return b.Type == \"NodeDocument\" // document root\n}","tryCatchPattern":"paths, err := model.Outline(id, false)\nif err != nil {\n    return err\n}\nif len(paths) == 0 {\n    // could be wrong id OR no headings; guide the user to disambiguate\n    return fmt.Errorf(\"no outline for %s: not a document, missing, or has no headings\", id)\n}","preventionTips":["Confirm the ID is a document root, not a paragraph/child block.","Documents without heading blocks yield empty outlines — add at least one heading."],"tags":["cli","outline","validation","not-found","empty-state"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}