chenhg5/cc-connect · error

%s: upload audio: no file_key returned

Error message

%s: upload audio: no file_key returned

What it means

After a supposedly successful upload, SendAudio validates that the response contains a file_key (uploadResp.Data.FileKey). If the response body has no Data or no FileKey pointer, this error is thrown because a voice message cannot be built without the key. It indicates an unexpected API response shape — the SDK reported Success but returned an empty payload.

Source

Thrown at platform/feishu/feishu.go:5503

					FileName("tts_audio.opus").
					File(bytes.NewReader(audio)).
					Build()).
				Build()
			var err error
			uploadResp, err = client.Im.File.Create(ctx, req, options...)
			if err != nil {
				return fmt.Errorf("%s: upload audio: %w", p.tag(), err)
			}
			if !uploadResp.Success() {
				return fmt.Errorf("%s: upload audio code=%d msg=%s", p.tag(), uploadResp.Code, uploadResp.Msg)
			}
			return nil
		})
	}); err != nil {
		return err
	}
	if uploadResp.Data == nil || uploadResp.Data.FileKey == nil {
		return fmt.Errorf("%s: upload audio: no file_key returned", p.tag())
	}
	fileKey := *uploadResp.Data.FileKey

	slog.Debug(p.tag()+": audio uploaded", "file_key", fileKey, "format", format, "size", len(audio))

	audioMsg := larkim.MessageAudio{FileKey: fileKey}
	audioContent, err := audioMsg.String()
	if err != nil {
		return fmt.Errorf("%s: build audio message: %w", p.tag(), err)
	}

	// Diagnostic for QA-reported intermittent "audio rendered as file" in
	// P2P reply mode (see internal task t-20260615-cqjbk1). Tracking the
	// API path lets operators correlate Feishu client renders to whether
	// we used Reply (in-thread) or Create (new message) when issues
	// recur. The Reply path has historically had narrower MsgType
	// support on some Feishu desktop client versions.
	if p.shouldUseThreadOrReplyAPI(rc) {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Pin/verify the github.com/larksuite/oapi-sdk version matches what this platform expects (go.mod / go.sum)
  2. Log the full uploadResp JSON when this occurs and compare against Feishu docs
  3. Retry — if intermittent, it may be a transient Feishu-side anomaly
  4. Check for proxies/middleboxes altering response bodies
Defensive patterns

Strategy: validation

Validate before calling

// after any Feishu upload, before using the result
if uploadResp == nil || uploadResp.Data == nil || uploadResp.Data.FileKey == nil || *uploadResp.Data.FileKey == "" {
    return errors.New("feishu: upload returned no file_key")
}

Type guard

func validFileKey(r *larkim.CreateFileResp) bool { return r != nil && r.Data != nil && r.Data.FileKey != nil && *r.Data.FileKey != "" }

Try / catch

if err := p.SendAudio(ctx, rc, audio, "opus"); err != nil && strings.Contains(err.Error(), "no file_key") {
    // retry once; if persistent, pin SDK version / check proxy
}

Prevention

When it happens

Trigger: Feishu's Im.File.Create returns a 200/Success envelope with an empty or malformed body: partial outage, API contract change in the SDK/lark version, or a proxy that strips/degrades the response body.

Common situations: Upgrading the larksuite/lark SDK to a version with a changed response schema; corporate proxy mangling JSON responses; Feishu incident causing truncated bodies.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/2b4c8a2ef7fba970. Report an issue: GitHub.