googleapis/mcp-toolbox · error

failed to update instance: %w

Error message

failed to update instance: %w

What it means

This error wraps a failure from InstanceAdmin.UpdateInstanceWithClusters when applying a new display name (and cluster config) to an existing Bigtable instance. Failures typically stem from the instance not existing, insufficient IAM permissions, or an invalid update payload. The underlying API error is preserved via %w.

Source

Thrown at internal/sources/bigtable/admin_wrappers.go:56

		ClusterId:   clusterId,
		Zone:        zone,
		NumNodes:    numNodes,
	}
	err := s.InstanceAdmin.CreateInstance(ctx, conf)
	if err != nil {
		return nil, fmt.Errorf("failed to create instance: %w", err)
	}
	return map[string]string{"status": "instance created successfully"}, nil
}

func (s *Source) UpdateInstance(ctx context.Context, instanceId, displayName string) (any, error) {
	conf := &bigtable.InstanceWithClustersConfig{
		InstanceID:  instanceId,
		DisplayName: displayName,
	}
	err := s.InstanceAdmin.UpdateInstanceWithClusters(ctx, conf)
	if err != nil {
		return nil, fmt.Errorf("failed to update instance: %w", err)
	}
	return map[string]string{"status": "instance updated successfully"}, nil
}

func (s *Source) DeleteInstance(ctx context.Context, instanceId string) (any, error) {
	err := s.InstanceAdmin.DeleteInstance(ctx, instanceId)
	if err != nil {
		return nil, fmt.Errorf("failed to delete instance: %w", err)
	}
	return map[string]string{"status": "instance deleted successfully"}, nil
}

func (s *Source) ListInstances(ctx context.Context) (any, error) {
	instances, err := s.InstanceAdmin.Instances(ctx)
	if err != nil {
		var partialErr bigtable.ErrPartiallyUnavailable
		if errors.As(err, &partialErr) {
			return instances, nil

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Confirm the instance exists: `gcloud bigtable instances list` and match the ID exactly.
  2. Ensure the service account has roles/bigtable.admin (update requires admin-level permission).
  3. Check the wrapped status code: NotFound -> fix instance ID; PermissionDenied -> fix IAM; Unavailable -> retry.
  4. Guard against empty instanceId/displayName before calling the API.
  5. Retry with backoff on transient codes (Unavailable, DeadlineExceeded).

Example fix

// before
err := s.InstanceAdmin.UpdateInstanceWithClusters(ctx, conf)
if err != nil {
    return nil, fmt.Errorf("failed to update instance: %w", err)
}
// after
if instanceId == "" {
    return nil, fmt.Errorf("instanceId is required")
}
err := s.InstanceAdmin.UpdateInstanceWithClusters(ctx, conf)
if err != nil {
    if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound {
        return nil, fmt.Errorf("instance %q not found; cannot update: %w", instanceId, err)
    }
    return nil, fmt.Errorf("failed to update instance %q: %w", instanceId, err)
}
Defensive patterns

Strategy: validation

Validate before calling

if instanceId == "" || displayName == "" {
    return errors.New("both instanceId and displayName are required to update an instance")
}
if _, err := src.GetInstance(ctx, instanceId); err != nil {
    return fmt.Errorf("instance %q does not exist; cannot update: %w", instanceId, err)
}

Type guard

func isUpdatePermissionError(err error) bool {
    st, ok := status.FromError(err)
    return ok && st.Code() == codes.PermissionDenied
}

Try / catch

_, err := src.UpdateInstance(ctx, id, name)
if err != nil {
    if isNotFound(err) {
        return fmt.Errorf("cannot update %q: instance not found", id)
    }
    if isUpdatePermissionError(err) {
        return fmt.Errorf("needs roles/bigtable.admin to update: %w", err)
    }
    var st *status.Status
    if errors.As(err, &st) && (st.Code() == codes.Unavailable || st.Code() == codes.DeadlineExceeded) {
        // safe to retry with backoff
    }
    return err
}

Prevention

When it happens

Trigger: Calling UpdateInstance(ctx, instanceId, displayName) for a non-existent instance ID, with a principal lacking bigtable.instances.update (roles/bigtable.admin), or with a config the API rejects (e.g. empty instance ID).

Common situations: LLM/tool caller hallucinating an instance name, credentials from the wrong project, attempting to update an instance concurrently deleted by another job, or permission downgrade after rotating service accounts.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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