chenhg5/cc-connect · error

%s: upload audio code=%d msg=%s

Error message

%s: upload audio code=%d msg=%s

What it means

The Feishu file-upload API returned HTTP success but a business-error body: uploadResp.Success() is false. The error surfaces the numeric Feishu code and msg. This is an API-level rejection of the upload itself — typically file constraints, permissions, or app configuration — not a transport problem.

Source

Thrown at platform/feishu/feishu.go:5495

	}

	var uploadResp *larkim.CreateFileResp
	if err := p.withTransientRetry(ctx, "upload audio", func() error {
		return p.withFreshTenantAccessTokenRetry(ctx, "upload audio", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {
			req := larkim.NewCreateFileReqBuilder().
				Body(larkim.NewCreateFileReqBodyBuilder().
					FileType(larkim.FileTypeOpus).
					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)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Look up the specific code=%d in Feishu's error-code documentation
  2. Grant the bot im:resource (file upload) scope and republish
  3. Check the audio size/duration against Feishu upload limits
  4. Confirm the app is installed and approved in the target tenant/workspace

Example fix

// before: ignoring the coded error
if err := p.SendAudio(ctx, rc, audio, "opus"); err != nil { return nil }
// after
if err := p.SendAudio(ctx, rc, audio, "opus"); err != nil {
    if strings.Contains(err.Error(), "code=230013") { slog.Warn("feishu: file too large") }
    return err
}
Defensive patterns

Strategy: validation

Validate before calling

// before upload: check audio size
const maxFeishuUpload = 30 << 20 // check current Feishu limit
if len(audio) > maxFeishuUpload { return errors.New("audio exceeds Feishu upload limit") }

Try / catch

if err := p.SendAudio(ctx, rc, audio, "opus"); err != nil {
    if code, ok := feishuCodeFrom(err); ok {
        switch code {
        case 230013: /* file too large */ ...
        default: slog.Error("feishu upload rejected", "code", code)
        }
    }
}

Prevention

When it happens

Trigger: client.Im.File.Create completes but the response body carries a non-zero code: file too large or wrong type for the im file endpoint, missing im:resource scope, invalid file_type parameter, or app not approved for the workspace.

Common situations: Audio exceeding Feishu's upload size limit; bot app missing im:resource permission in the Feishu admin console; uploading to a tenant where the app is not installed/approved; Feishu-side API changes after version updates.

Related errors


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