{"record":{"id":"bc480708e4607f9a","repo":"amir20/dozzle","slug":"cloud-search-w","errorCode":null,"errorMessage":"cloud: search: %w","messagePattern":"cloud: search: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/search.go","lineNumber":102,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmdPairs := []string{\"x-api-key\", apiKey}\n\tif c.instanceID != \"\" {\n\t\tmdPairs = append(mdPairs, \"x-instance-id\", c.instanceID)\n\t}\n\tcallCtx := metadata.NewOutgoingContext(ctx, metadata.Pairs(mdPairs...))\n\n\tresp, err := client.SearchLogs(callCtx, &pb.SearchLogsRequest{\n\t\tQuery:       query,\n\t\tLimit:       limit,\n\t\tHostId:      hostID,\n\t\tContainerId: containerID,\n\t\tBeforeTsNs:  before,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cloud: search: %w\", err)\n\t}\n\n\thits := make([]SearchLogHit, 0, len(resp.GetHits()))\n\tfor _, h := range resp.GetHits() {\n\t\thits = append(hits, SearchLogHit{\n\t\t\tTimestampNs:   h.GetTimestampNs(),\n\t\t\tHostID:        h.GetHostId(),\n\t\t\tContainerID:   h.GetContainerId(),\n\t\t\tContainerName: h.GetContainerName(),\n\t\t\tMessage:       h.GetMessage(),\n\t\t\tStream:        h.GetStream(),\n\t\t\tLevel:         h.GetLevel(),\n\t\t\tLogID:         h.GetLogId(),\n\t\t})\n\t}\n\treturn &SearchLogResult{\n\t\tHits:       hits,\n\t\tHasMore:    resp.GetHasMore(),","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/cloud/search.go#L84-L120","documentation":"SearchLogs issues a cloud-side log search RPC (with limit, host/container IDs, and a before-timestamp) and wraps any RPC error as 'cloud: search: %w'. The failure comes from the gRPC call itself, not the search results. The underlying status is preserved for programmatic handling.","triggerScenarios":"Calling SearchLogs when the cloud RPC fails: connection dropped, PermissionDenied from an invalid API key, invalid arguments rejected server-side, or a deadline/context cancellation.","commonSituations":"Cloud service outage, account without pro plan, oversized or out-of-range query parameters (limit/timestamps) rejected by the server, network egress blocked in restricted deployments.","solutions":["Unwrap and inspect the gRPC status code (codes.PermissionDenied means API key/plan issue)","Validate limit and timestamp inputs are within server-accepted ranges before the call","Check connectivity to the cloud endpoint and retry with backoff for transient codes","Confirm the host/container IDs exist and are accessible to the account"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if limit <= 0 || limit > maxSearchLimit {\n    return fmt.Errorf(\"limit must be 1..%d\", maxSearchLimit)\n}\nif before < 0 {\n    return fmt.Errorf(\"before timestamp must be non-negative\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := client.SearchLogs(ctx, req)\nif err != nil {\n    if status.Code(err) == codes.PermissionDenied { return nil, err }\n    if status.Code(err) == codes.Unavailable {\n        time.Sleep(backoff); return retry(req)\n    }\n    return nil, err\n}","preventionTips":["Clamp limit and timestamps to server-accepted ranges before calling","Set explicit context deadlines","Handle PermissionDenied as non-retryable","Monitor cloud endpoint availability"],"tags":["grpc","cloud","search","api","network"],"backgroundTag":"api-request-failed","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}