{"record":{"id":"d91c6a803c81f695","repo":"kubernetes/kops","slug":"error-parsing-operation-url-q-v","errorCode":null,"errorMessage":"error parsing operation URL %q: %v","messagePattern":"error parsing operation URL %q: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/op.go","lineNumber":40,"sourceCode":"import (\n\t\"fmt\"\n\t\"time\"\n\n\tcompute \"google.golang.org/api/compute/v1\"\n\t\"google.golang.org/api/googleapi\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\toperationPollInterval        = 3 * time.Second\n\toperationPollTimeoutDuration = 30 * time.Minute\n)\n\nfunc WaitForOp(client *compute.Service, op *compute.Operation) error {\n\tu, err := ParseGoogleCloudURL(op.SelfLink)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing operation URL %q: %v\", op.SelfLink, err)\n\t}\n\n\tif u.Zone != \"\" {\n\t\treturn waitForZoneOp(client, op)\n\t}\n\n\tif u.Region != \"\" {\n\t\treturn waitForRegionOp(client, op)\n\t}\n\n\treturn waitForGlobalOp(client, op)\n}\n\nfunc waitForZoneOp(client *compute.Service, op *compute.Operation) error {\n\tu, err := ParseGoogleCloudURL(op.SelfLink)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing operation URL %q: %v\", op.SelfLink, err)\n\t}","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/op.go#L22-L58","documentation":"WaitForOp parses the operation's SelfLink via ParseGoogleCloudURL to decide whether the operation is zonal, regional, or global. If the SelfLink cannot be parsed as a Google Cloud URL, this error is returned immediately instead of polling. It indicates the compute.Operation object contains a malformed or unexpected SelfLink.","triggerScenarios":"A compute.Operation returned by the API (or fabricated in tests/mocks) whose SelfLink field is empty, truncated, or in an unexpected format, passed into WaitForOp.","commonSituations":"Mock/stub operations in tests with fake SelfLinks; API responses from unusual endpoints or proxies; bugs in constructing operations when the compute API returns partial objects.","solutions":["Log the op.SelfLink value and verify it is a full Google Cloud URL (project, and optionally zone/region, plus operation name)","Retry the operation that produced the Operation object — a partial API response is often transient","If in tests, make mocks use realistic SelfLinks like https://www.googleapis.com/compute/v1/projects/P/zones/Z/operations/opName","Upgrade kops / google-api-go-client in case of a SelfLink format change"],"exampleFix":"// before\nop := &compute.Operation{Name: \"op-1\"}\nerr := WaitForOp(client, op)\n// after\nop := &compute.Operation{Name: \"op-1\", SelfLink: \"https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/operations/op-1\"}\nerr := WaitForOp(client, op)","handlingStrategy":"validation","validationCode":"func validOpSelfLink(op *compute.Operation) bool {\n\t_, err := gce.ParseGoogleCloudURL(op.SelfLink)\n\treturn err == nil\n}\nif !validOpSelfLink(op) { return fmt.Errorf(\"operation %s has invalid SelfLink %q\", op.Name, op.SelfLink) }","typeGuard":null,"tryCatchPattern":"if err := gce.WaitForOp(client, op); err != nil {\n\tif strings.Contains(err.Error(), \"error parsing operation URL\") {\n\t\tklog.Errorf(\"bad op SelfLink %q — refresh op via compute API and retry\", op.SelfLink)\n\t}\n\treturn err\n}","preventionTips":["Always obtain Operation objects from real compute API responses, never construct them by hand outside tests","In tests, populate SelfLink with canonical GCE URLs","Verify proxies/custom endpoints do not rewrite self-links","Refresh the operation from the API if its SelfLink looks empty or truncated"],"tags":["gce","operation","url-parsing"],"backgroundTag":"invalid-resource-url","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}