{"record":{"id":"02bb6c464ef87302","repo":"AlistGo/alist","slug":"s-v-02bb6c","errorCode":null,"errorMessage":"%s: %v","messagePattern":"%s: %v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/google_photo/driver.go","lineNumber":115,"sourceCode":"\t\t\"X-Goog-Upload-Raw-Size\":     strconv.FormatInt(stream.GetSize(), 10),\n\t}\n\turl := \"https://photoslibrary.googleapis.com/v1/uploads\"\n\tres, err := base.NoRedirectClient.R().SetHeaders(postHeaders).\n\t\tSetError(&e).\n\t\tPost(url)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\tif e.Error.Code != 0 {\n\t\tif e.Error.Code == 401 {\n\t\t\terr = d.refreshToken()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn d.Put(ctx, dstDir, stream, up)\n\t\t}\n\t\treturn fmt.Errorf(\"%s: %v\", e.Error.Message, e.Error.Errors)\n\t}\n\n\t//Upload to the Google Photo\n\tpostUrl := res.Header().Get(\"X-Goog-Upload-URL\")\n\t//chunkSize := res.Header().Get(\"X-Goog-Upload-Chunk-Granularity\")\n\tpostHeaders = map[string]string{\n\t\t\"X-Goog-Upload-Command\": \"upload, finalize\",\n\t\t\"X-Goog-Upload-Offset\":  \"0\",\n\t}\n\n\tresp, err := d.request(postUrl, http.MethodPost, func(req *resty.Request) {\n\t\treq.SetBody(driver.NewLimitedUploadStream(ctx, stream)).SetContext(ctx)\n\t}, nil, postHeaders)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\t//Create MediaItem","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/google_photo/driver.go#L97-L133","documentation":"Google Photo upload (Put) error: the upload-session init request (X-Goog-Upload-START style) returned a structured API error with non-zero code other than 401, formatted as '<message>: <errors>'. Google Photos is strictly quota-limited, so this is frequently an uploads quota or scope problem.","triggerScenarios":"Starting a media upload where init fails: libraryApiUpdatesDisabled (API access not enabled for the project), insufficient permissions (photoslibrary.appendonly scope missing), album quota exceeded, or malformed upload metadata.","commonSituations":"Google Photos API library not enabled in the Cloud project; OAuth token granted without the appendonly/uploads scope; hitting the 25,000-item or requests-per-minute limits; album is a shared album the token cannot write to.","solutions":["Enable the Google Photos Library API and request verification for restricted scopes in the Cloud project","Re-consent OAuth with the required upload scopes (photoslibrary.appendonly)","If quota reasons appear, pause uploads — Photos upload quotas reset daily and on a rolling window","Write to albums the credential owns or is explicitly granted write on"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isPhotosQuotaError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"Quota\") || strings.Contains(err.Error(), \"libraryApiUpdatesDisabled\")\n}","tryCatchPattern":"err := d.Put(ctx, dstDir, stream, up)\nif err != nil {\n  if strings.Contains(err.Error(), \"libraryApiUpdatesDisabled\") { /* API access problem: fix project config */ return err }\n  if strings.Contains(err.Error(), \"Quota\") { /* schedule retry after quota window resets */ }\n}","preventionTips":["Enable and verify the Photos Library API plus scope review before first upload","Batch media uploads with daily caps below Photos quota limits"],"tags":["google-photos","upload","quota","api"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}