googleapis/mcp-toolbox · error
object %q in bucket %q: %w
Error message
object %q in bucket %q: %w
What it means
The object's bytes were read successfully but are not valid UTF-8, so the source rejects them by wrapping cloudstoragecommon.ErrBinaryContent. The tool returns text content only, and binary data cannot be represented in the string response.
Source
Thrown at internal/sources/cloudstorage/cloudstorage.go:270
reader, err := s.client.Bucket(bucket).Object(object).NewRangeReader(ctx, offset, length)
if err != nil {
return nil, fmt.Errorf("failed to open object %q in bucket %q: %w", object, bucket, err)
}
defer reader.Close()
if remain := reader.Remain(); remain > defaultMaxReadBytes {
return nil, fmt.Errorf("object %q: %d bytes exceeds %d byte limit: %w",
object, remain, defaultMaxReadBytes,
cloudstoragecommon.ErrReadSizeLimitExceeded)
}
data, err := io.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("failed to read object %q in bucket %q: %w", object, bucket, err)
}
if !utf8.Valid(data) {
return nil, fmt.Errorf("object %q in bucket %q: %w", object, bucket,
cloudstoragecommon.ErrBinaryContent)
}
return map[string]any{
"content": string(data),
"contentType": reader.Attrs.ContentType,
"size": len(data),
}, nil
}
// ListBuckets lists buckets in a project. When project is empty, the source's
// configured project is used. maxResults == 0 returns up to the GCS per-page
// default (1000). A non-empty pageToken resumes listing. The returned map
// contains "buckets" ([]*storage.BucketAttrs) and "nextPageToken" (empty when
// there are no more results).
func (s *Source) ListBuckets(ctx context.Context, project, prefix string, maxResults int, pageToken string) (map[string]any, error) {
if project == "" {
project = s.ProjectView on GitHub (pinned to 8cc6e09de2)
Solutions
- Only call ReadObject on text objects; check the object's contentType (via ListObjects/metadata) is text/*, application/json, etc. first.
- For binary objects, download via gsutil/the GCS client instead of this text-oriented tool.
- If the file is meant to be text but fails UTF-8 validation, re-upload it after converting encoding (e.g. iconv to UTF-8).
- Handle ErrBinaryContent (errors.Is) in the caller and surface a friendly 'binary content not supported' message to the user.
Example fix
// before
res, err := source.ReadObject(ctx, "bkt", "images/logo.png", 0, -1) // binary
// after
if isTextContentType("image/png") == false { return errors.New("use a binary download path for this object") }
res, err := source.ReadObject(ctx, "bkt", "notes/readme.txt", 0, -1) Defensive patterns
Strategy: validation
Validate before calling
func isTextContentType(ct string) bool {
ct = strings.ToLower(ct)
return strings.HasPrefix(ct, "text/") || ct == "application/json" || ct == "application/yaml"
}
// check object contentType before ReadObject Type guard
func isBinaryContentErr(err error) bool {
return errors.Is(err, cloudstoragecommon.ErrBinaryContent)
} Try / catch
if errors.Is(err, cloudstoragecommon.ErrBinaryContent) {
return nil, fmt.Errorf("object is binary; use a download tool instead")
} Prevention
- Filter by contentType (text/*) before reading objects.
- Convert non-UTF-8 text files to UTF-8 at upload time.
- Handle ErrBinaryContent explicitly to give users a clear message.
- Don't bulk-read every object in a bucket; skip known binary prefixes (.png, .zip, .pdf).
When it happens
Trigger: ReadObject on binary objects: images (PNG/JPEG), archives (zip/tar.gz), PDFs, Parquet/Avro, or any file with invalid UTF-8 sequences anywhere in the read range.
Common situations: LLM user asking to 'read' a .png or .zip from a bucket; listing bucket contents and reading every object without filtering by content-type; offset/length windows landing inside multibyte or binary regions of mixed-encoding files.
Related errors
- failed to open object %q in bucket %q: %w
- object %q: %d bytes exceeds %d byte limit: %w
- failed to read object %q in bucket %q: %w
- ErrBinaryContent
- local path %q cannot be resolved for source %q: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/35dba1ace7f24a1f.
Report an issue: GitHub.