googleapis/mcp-toolbox · error

ErrDestinationExists

ErrDestinationExists

Error message

download destination already exists

What it means

ErrDestinationExists is returned by the download_object source method when the local destination file already exists and overwrite is false. DownloadObject maps the underlying os.ErrExist from file creation to this sentinel, and ProcessGCSError classifies it as an Agent error so the LLM can retry with overwrite=true. It prevents accidental clobbering of existing local files.

Source

Thrown at internal/tools/cloudstorage/cloudstoragecommon/errors.go:49

// would exceed the source's configured byte limit. ProcessGCSError maps this
// to an Agent error because the LLM can fix the call by narrowing the 'range'
// parameter.
var ErrReadSizeLimitExceeded = errors.New("cloud storage read size limit exceeded")

// ErrBinaryContent is returned by the source when an object's bytes are not
// valid UTF-8. The MCP tool result channel only carries text today, so binary
// payloads cannot be faithfully round-tripped; ProcessGCSError maps this to an
// Agent error so the LLM knows to stop asking for this object.
//
// TODO: when the toolbox supports non-text MCP content (embedded resources,
// images, blobs), remove this guard and return binary payloads directly.
var ErrBinaryContent = errors.New("cloud storage object is not valid UTF-8 text")

// ErrDestinationExists is returned by the download_object source method when
// the local destination file already exists and overwrite is false.
// ProcessGCSError maps this to an Agent error so the LLM can retry the call
// with overwrite=true.
var ErrDestinationExists = errors.New("download destination already exists")

// ProcessGCSError classifies an error from the Cloud Storage Go client into
// either an Agent Error (the LLM can self-correct by changing its input — bad
// request, missing bucket/object, unsatisfiable range) or a Server Error
// (infrastructure failure — auth, IAM denial, quota, 5xx, network
// cancellation). See DEVELOPER.md "Tool Invocation & Error Handling" for the
// wider rationale.
func ProcessGCSError(err error) util.ToolboxError {
	if err == nil {
		return nil
	}

	// Transport-level cancellation/timeout — treat as infrastructure. These
	// checks come first because a wrapped googleapi.Error on top of a
	// cancelled context should still surface as a server error.
	if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
		return util.NewClientServerError(
			"cloud storage request cancelled or timed out",

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Retry the download call with overwrite=true to replace the existing destination file.
  2. Choose a different destination path that does not exist.
  3. Delete or move the existing file before retrying if preservation of the old copy matters.

Example fix

// before
download_object(bucket="exports", object="report.csv", destination="/tmp/report.csv") // -> ErrDestinationExists
// after
download_object(bucket="exports", object="report.csv", destination="/tmp/report.csv", overwrite=true)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(destination); err == nil && !overwrite {
    destination = fmt.Sprintf("%s.%d.bak", destination, time.Now().Unix())
}

Try / catch

if errors.Is(err, cloudstoragecommon.ErrDestinationExists) {
    // retry once with overwrite=true or pick a new destination
}

Prevention

When it happens

Trigger: Calling download_object (GCS) where os.OpenFile/os.Create on the destination path returns os.ErrExist — i.e. the local file exists and overwrite was not set to true.

Common situations: Re-running a download step after a previous successful run left the file in place; agent retrying a partially completed workflow; a fixed destination filename reused across downloads.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/e225a16fa4294e82. Report an issue: GitHub.