googleapis/mcp-toolbox · error

invalid operation name: %q

Error message

invalid operation name: %q

What it means

After CreateDataProduct submits the LRO, the library parses the returned long-running operation's name (expected form projects/{p}/locations/{l}/operations/{id}) to extract locationId and operationId. If the name does not match that shape, this error is thrown because the operation identifier cannot be interpreted.

Source

Thrown at internal/sources/dataplex/dataplex.go:678

		Parent:        parent,
		DataProductId: dataProductID,
		DataProduct: &dataplexpb.DataProduct{
			DisplayName:  displayName,
			Description:  description,
			OwnerEmails:  ownerEmails,
			AccessGroups: agMap,
		},
	}

	op, err := s.GetDataProductClient().CreateDataProduct(ctx, req)
	if err != nil {
		return nil, err
	}

	opName := op.Name()
	parts := strings.Split(opName, "/")
	if len(parts) < 6 || parts[0] != "projects" || parts[2] != "locations" || parts[4] != "operations" {
		return nil, fmt.Errorf("invalid operation name: %q", opName)
	}
	return map[string]string{
		"locationId":  parts[3],
		"operationId": parts[5],
	}, nil
}

func (s *Source) UpdateDataProduct(
	ctx context.Context,
	locationID string,
	dataProductID string,
	description string,
	displayName string,
	ownerEmails []string,
	accessGroups []AccessGroup,
	updateMask []string,
) (map[string]string, error) {
	name := fmt.Sprintf("projects/%s/locations/%s/dataProducts/%s", s.ProjectID(), locationID, dataProductID)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Log op.Name() to inspect the actual format returned.
  2. Update the library/SDK to the latest version in case of a name-format change.
  3. If using a mock/fake Dataplex client, make it return a properly formatted operation name 'projects/P/locations/L/operations/OP'.
  4. Retry the create call; if persistent, capture the raw response and report to the library maintainers.

Example fix

// before (mock returning empty op)
op := &longrunningpb.Operation{}
// after
op := &longrunningpb.Operation{Name: "projects/my-proj/locations/us-central1/operations/abc123"}
Defensive patterns

Strategy: type-guard

Type guard

func parseLROName(name string) (locID, opID string, ok bool) {
	parts := strings.Split(name, "/")
	if len(parts) < 6 || parts[0] != "projects" || parts[2] != "locations" || parts[4] != "operations" {
		return "", "", false
	}
	return parts[3], parts[5], true
}

Try / catch

op, err := src.CreateDataProduct(ctx, params)
if err != nil {
	if strings.Contains(err.Error(), "invalid operation name") {
		log.Printf("unexpected LRO name format; check SDK version / mock setup")
	}
	return err
}

Prevention

When it happens

Trigger: op.Name() from the Dataplex CreateDataProduct LRO returns a string that splits into fewer than 6 path segments or whose segments 0/2/4 are not projects/locations/operations — e.g. an empty name from a malformed API response or an unexpected name format.

Common situations: A Dataplex API/SDK behavior change altering operation name format; a stubbed or mocked client returning an empty operation name; proxy or test fake returning a partially populated LongRunningOperation.

Related errors


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