siyuan-note/siyuan · warning

document not found or has no headings

Error message

document not found or has no headings

What it means

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.

Source

Thrown at kernel/cli/cmd/outline.go:47

var outlineCmd = &cobra.Command{
	Use:   "outline",
	Short: "Document outline (heading tree)",
}

var outlineGetCmd = &cobra.Command{
	Use:   "get --id <id>",
	Short: "Get document outline",
	RunE: func(cmd *cobra.Command, args []string) error {
		id, _ := cmd.Flags().GetString("id")
		if id == "" {
			return fmt.Errorf("--id is required")
		}
		paths, err := model.Outline(id, false)
		if err != nil {
			return err
		}
		if len(paths) == 0 {
			return fmt.Errorf("document not found or has no headings")
		}
		switch outputFormat {
		case "json":
			data, _ := json.MarshalIndent(paths, "", "  ")
			fmt.Println(string(data))
		default:
			var sb strings.Builder
			sb.WriteString(fmt.Sprintf("Document outline (%d headings):\n\n", countOutlineHeadings(paths)))
			for _, p := range paths {
				writeOutlinePath(&sb, p, 0)
			}
			fmt.Print(sb.String())
		}
		return nil
	},
}

func countOutlineHeadings(paths []*model.Path) int {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Confirm the ID is a document root ID (not a child block) via `block get` or the editor.
  2. Ensure the target document actually contains heading blocks.
  3. Verify the document still exists in the current workspace.

Example fix

# before
siyuan outline get --id 202406011200-paragraphblock
got: document not found or has no headings
# after (use the document root id, and ensure it has headings)
siyuan outline get --id 202406011200-docroot
Defensive patterns

Strategy: type-guard

Validate before calling

# verify the id is a real document with headings before calling outline
id="$DOC_ID"
siyuan block get --id "$id" >/dev/null 2>&1 || { echo "block missing"; exit 1; }

Type guard

// Distinguish 'no such document' from 'document has no headings' by
// checking the block exists and is a document root before outlining.
func isDocumentRoot(id string) bool {
    b, err := model.GetBlock(id)
    if err != nil || b == nil {
        return false
    }
    return b.Type == "NodeDocument" // document root
}

Try / catch

paths, err := model.Outline(id, false)
if err != nil {
    return err
}
if len(paths) == 0 {
    // could be wrong id OR no headings; guide the user to disambiguate
    return fmt.Errorf("no outline for %s: not a document, missing, or has no headings", id)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/9dec1883f1a397c5. Report an issue: GitHub.