chenhg5/cc-connect · error

download file %s: status %d

Error message

download file %s: status %d

What it means

Returned when the file download HTTP request completes but the status code is not 200 OK. The body may contain an error page or nothing useful, so the platform refuses to parse it and reports the exact status code alongside the file_id.

Source

Thrown at platform/telegram/telegram.go:1366

		return nil, err
	}
	ctx := context.Background()
	f, err := bot.GetFile(ctx, &tgbot.GetFileParams{FileID: fileID})
	if err != nil {
		return nil, fmt.Errorf("get file: %w", err)
	}
	if f.FilePath == "" {
		return nil, fmt.Errorf("get file: empty file_path returned for file_id %s", fileID)
	}
	link := bot.FileDownloadLink(f)

	resp, err := p.httpClient.Get(link)
	if err != nil {
		return nil, fmt.Errorf("download file %s: %w", fileID, err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("download file %s: status %d", fileID, resp.StatusCode)
	}
	return io.ReadAll(resp.Body)
}

func (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error) {
	// Formats:
	//   telegram:{chatID}                      - shared session, no topic
	//   telegram:{chatID}:{threadID}           - shared session, with topic
	//   telegram:{chatID}:{userID}             - per-user session, no topic
	//   telegram:{chatID}:{threadID}:{userID}  - per-user session, with topic
	parts := strings.SplitN(sessionKey, ":", 5)
	if len(parts) < 2 || parts[0] != "telegram" {
		return nil, fmt.Errorf("telegram: invalid session key %q", sessionKey)
	}
	chatID, err := strconv.ParseInt(parts[1], 10, 64)
	if err != nil {
		return nil, fmt.Errorf("telegram: invalid chat ID in %q", sessionKey)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Re-fetch the file via getFile to obtain a fresh file_path immediately before downloading — paths expire (~1 hour TTL).
  2. Check the status code in the message: 404/400 usually means expired or wrong path; 5xx means retry later.
  3. Retry with exponential backoff on 5xx responses.
  4. Confirm bot.FileDownloadLink builds the URL correctly for your bot API client version.

Example fix

// before
link := bot.FileDownloadLink(f) // possibly stale
resp, _ := p.httpClient.Get(link)
// after: refresh metadata right before download
f, err := bot.GetFile(ctx, &tgbot.GetFileParams{FileID: fileID})
if err != nil { return nil, err }
resp, err := p.httpClient.Get(bot.FileDownloadLink(f))
Defensive patterns

Strategy: retry

Validate before calling

// download immediately after getFile; paths expire (~1h TTL)
if time.Since(fetchedAt) > time.Hour { /* re-run GetFile */ }

Try / catch

resp, err := p.httpClient.Get(link)
if err != nil { return nil, err }
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusBadRequest {
    // refresh file_path via GetFile, then retry once
}
if resp.StatusCode != http.StatusOK {
    return nil, fmt.Errorf("download file %s: status %d", fileID, resp.StatusCode)
}

Prevention

When it happens

Trigger: p.httpClient.Get(link) succeeds but resp.StatusCode != http.StatusOK — e.g. 404 for an expired/invalid file path, 400 bad request, 5xx from Telegram's file server.

Common situations: Stale file_path: Telegram file paths expire after about an hour, so late downloads get 400/404; malformed link from an empty/odd file_path; Telegram file-server incidents returning 5xx.

Related errors


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