larksuite/cli · error

@%s: %w

Error message

@%s: %w

What it means

During slides creation, uploadSlidesPlaceholders uploads each '@path' placeholder file via uploadSlidesMedia. If an upload fails after the file was validated as a regular file, the error is re-wrapped as '@<path>: <cause>' preserving the typed cause with %w; the call site (appendSlidesProgressHint) reclassifies it. The wrapping only adds which placeholder file failed.

Source

Thrown at shortcuts/slides/slides_create.go:420

// presentation and returns the path→file_token map. The second return value is
// the number of files successfully uploaded before any error, so callers can
// surface progress in the failure message. param names the flag the XML came
// from, so an error points at the flag the caller actually typed.
func uploadSlidesPlaceholders(runtime *common.RuntimeContext, presentationID string, paths []string, param string) (map[string]string, int, error) {
	tokens := make(map[string]string, len(paths))
	for i, path := range paths {
		stat, err := runtime.FileIO().Stat(path)
		if err != nil {
			return tokens, i, slidesInputStatError(err, param, fmt.Sprintf("@%s", path))
		}
		if !stat.Mode().IsRegular() {
			return tokens, i, errs.NewValidationError(errs.SubtypeInvalidArgument, "@%s: must be a regular file", path).WithParam(param)
		}
		fileName := filepath.Base(path)

		token, err := uploadSlidesMedia(runtime, path, fileName, stat.Size(), presentationID)
		if err != nil {
			return tokens, i, fmt.Errorf("@%s: %w", path, err) //nolint:forbidigo // intermediate; preserves typed cause via %w, reclassified by appendSlidesProgressHint at the call site
		}
		tokens[path] = token
	}
	return tokens, len(paths), nil
}

// xmlEscape escapes special XML characters in text content.
func xmlEscape(s string) string {
	s = strings.ReplaceAll(s, "&", "&amp;")
	s = strings.ReplaceAll(s, "<", "&lt;")
	s = strings.ReplaceAll(s, ">", "&gt;")
	s = strings.ReplaceAll(s, "\"", "&quot;")
	s = strings.ReplaceAll(s, "'", "&apos;")
	return s
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the wrapped cause after '@path:' — it identifies the underlying failure (auth, size, type, network) to fix.
  2. Verify the file exists, is readable, and is a supported media type/size for Slides.
  3. Re-run authentication (lark auth) if the cause indicates token/scope problems.
  4. Retry on transient network errors; for large files check size limits before upload.

Example fix

// before (file removed between check and upload)
lark slides create --title t --content "@/tmp/missing.png"
// after
ls -l /tmp/missing.png  # ensure present & readable, then re-run
Defensive patterns

Strategy: try-catch

Validate before calling

info, err := os.Stat(path)
if err != nil || !info.Mode().IsRegular() {
	return fmt.Errorf("@%s: must be a regular file", path)
}
if info.Size() > maxSlidesMediaBytes { return fmt.Errorf("@%s: file too large", path) }

Try / catch

token, err := upload(...)
if err != nil {
	var ve *errs.ValidationError
	if errors.As(err, &ve) { log.Printf("placeholder %s rejected: param=%s", path, ve.Param) }
	if isRetryable(err) { return retryUpload(path) }
	return fmt.Errorf("@%s: %w", path, err)
}

Prevention

When it happens

Trigger: Calling slides create/update with '@file' placeholders where uploadSlidesMedia fails for one of the files — e.g. unreadable file after stat, file too large for slides media, unsupported media type, or a network/API error during the media upload to the presentation.

Common situations: Files deleted or permissions changed between validation and upload; non-media or oversized assets; expired/insufficient auth token for media upload endpoints; transient network failures during large uploads.

Related errors


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