larksuite/cli · error

missing start element

Error message

missing start element

What it means

parseHTML5BlockStartTag scans tokens until the first xml.StartElement; if the fragment is exhausted (EOF) without ever seeing a start element — the input is empty, contains only text/comments/processing instructions, or is self-closing markup the tokenizer did not surface as an element — it returns 'missing start element'. Callers wrap it in typed validation errors.

Source

Thrown at shortcuts/doc/html5_block_resources.go:895

			if errors.Is(err, io.EOF) {
				break
			}
			return html5BlockStartTag{}, err
		}
		start, ok := tok.(xml.StartElement)
		if !ok {
			continue
		}
		if start.Name.Local != html5BlockTag {
			return html5BlockStartTag{}, fmt.Errorf("expected <%s>, got <%s>", html5BlockTag, start.Name.Local) //nolint:forbidigo // intermediate parse helper; callers wrap with typed validation errors.
		}
		attrs := make([]html5BlockAttr, 0, len(start.Attr))
		for _, attr := range start.Attr {
			attrs = append(attrs, html5BlockAttr{Name: attr.Name.Local, Value: attr.Value})
		}
		return html5BlockStartTag{Attrs: attrs, SelfClosing: selfClosing}, nil
	}
	return html5BlockStartTag{}, fmt.Errorf("missing start element") //nolint:forbidigo // intermediate parse helper; callers wrap with typed validation errors.
}

func parseWhiteboardStartTag(raw string) (whiteboardStartTag, error) {
	trimmed := strings.TrimSpace(raw)
	selfClosing := strings.HasSuffix(trimmed, "/>")
	decoder := xml.NewDecoder(strings.NewReader(raw))
	for {
		tok, err := decoder.Token()
		if err != nil {
			if errors.Is(err, io.EOF) {
				break
			}
			return whiteboardStartTag{}, err
		}
		start, ok := tok.(xml.StartElement)
		if !ok {
			continue
		}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check the raw fragment in the wrapped error; verify the block wrapper actually exists in the source document.
  2. Re-export or re-convert the document so the expected HTML5 block structure is regenerated.
  3. If processing programmatically, validate the fragment contains a start element (e.g. via xml.Decoder peek) before calling the rewrite API.
Defensive patterns

Strategy: validation

Validate before calling

// Verify the fragment contains an element before rewriting:
trimmed := strings.TrimSpace(fragment)
if trimmed == "" || !strings.Contains(trimmed, "<") {
    return errs.NewValidationError(errs.SubtypeInvalidArgument, "empty html5 block fragment")
}

Type guard

func fragmentHasStartElement(fragment string) bool {
    dec := xml.NewDecoder(strings.NewReader(fragment))
    for {
        tok, err := dec.Token()
        if err != nil { return false }
        if _, ok := tok.(xml.StartElement); ok { return true }
    }
}

Try / catch

out, err := parseHTML5BlockStartTag(raw)
if err != nil {
    return errs.NewValidationError(errs.SubtypeInvalidArgument, "html5 block missing wrapper: %s", err).WithCause(err)
}

Prevention

When it happens

Trigger: Rewriting a doc resource block where the extracted start-tag fragment is empty, whitespace/comment-only, plain text, or otherwise contains no element token.

Common situations: Doc content where the expected block wrapper is absent (already-flattened content), empty resource placeholders, or upstream extraction bugs slicing markup incorrectly.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/82d5e6199a3f3c8d. Report an issue: GitHub.