larksuite/cli · error

note detail is empty

Error message

note detail is empty

What it means

ErrEmptyDetail is the sentinel cause identifying a note detail response from GET /open-apis/vc/v1/notes/{note_id} that succeeded at the HTTP/API level but contains no `note` object in the payload. FetchDetail wraps it in a typed errs.InternalError (subtype invalid_response) via WithCause, so callers should match errors.Is(err, ErrEmptyDetail) rather than the display text. It means the API returned an unexpected/invalid response shape, not an auth or transport failure.

Source

Thrown at shortcuts/note/note.go:30

	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/larksuite/cli/errs"
	"github.com/larksuite/cli/internal/validate"
	"github.com/larksuite/cli/shortcuts/common"
)

// NoNoteReadPermissionCode is returned when the caller lacks read permission
// for the requested note.
const NoNoteReadPermissionCode = 121005

// ErrEmptyDetail identifies note detail responses that do not contain a note
// object. Callers should use errors.Is instead of matching the display message.
var ErrEmptyDetail = errors.New("note detail is empty")

// artifact_type enum from the note detail API.
const (
	artifactTypeMainDoc  = 1 // main note document
	artifactTypeVerbatim = 2 // verbatim transcript
)

// note_display_type enum (i32) from the note detail API. Surfaced to callers as
// a stable string so Agents route on a name, not a magic number.
const (
	displayTypeNormal  = 1
	displayTypeUnified = 2
)

// Detail is the parsed note detail shared by `note +detail` and `vc +notes`.
type Detail struct {
	NoteID           string
	CreatorID        string

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Verify the note_id is correct and the note still exists/opens in the Lark client; retry with a valid note ID.
  2. Check the caller has read permission for the note (permission failures surface via code 121005 / NoNoteReadPermissionCode paths, but exotic permission states can yield empty payloads).
  3. Match errors.Is(err, ErrEmptyDetail) in code and surface a 'note detail unavailable' message instead of retrying blindly.
  4. If it persists on known-good notes, capture the raw response and report a possible API shape change.

Example fix

// before
detail, err := note.FetchDetail(ctx, runtime, noteID)
if err != nil { return err }
// after
detail, err := note.FetchDetail(ctx, runtime, noteID)
if errors.Is(err, note.ErrEmptyDetail) {
    return fmt.Errorf("note %s has no retrievable detail; check it exists and is shared with you", noteID)
} else if err != nil {
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

// validate the note_id is a non-empty plausible token before calling
if noteID == "" || strings.ContainsAny(noteID, "/?# ") {
    return fmt.Errorf("invalid note id %q", noteID)
}

Type guard

detail, err := note.FetchDetail(ctx, runtime, noteID)
if err != nil {
    if errors.Is(err, note.ErrEmptyDetail) { /* invalid-response path */ }
    return err
}

Try / catch

detail, err := note.FetchDetail(ctx, runtime, noteID)
if errors.Is(err, note.ErrEmptyDetail) {
    return fmt.Errorf("note detail unavailable for %s; verify the note exists and is readable", noteID)
}
if err != nil {
    return err
}

Prevention

When it happens

Trigger: Calling shortcuts/note FetchDetail (backing `note +detail` and `vc +notes`) where the decoded JSON response has data["note"] missing, null, or not a JSON object (e.g. an unexpected envelope change or an odd note state the API returns with code 0 but no note payload).

Common situations: Fetching a note that exists in an unusual state (deleted/draft/permission-limited) where the backend returns an empty payload with success code; a Lark/Feishu API response-shape change; passing a note_id that resolves but has no retrievable detail.

Related errors


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