{"record":{"id":"2ecf39fd80ff00af","repo":"infiniflow/ragflow","slug":"failed-to-delete-memory","errorCode":null,"errorMessage":"Failed to delete memory","messagePattern":"Failed to delete memory","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/pages/memories/hooks.ts","lineNumber":174,"sourceCode":"\n  return { data: data?.data, isLoading, isError };\n};\n\nexport const useDeleteMemory = () => {\n  const { t } = useTranslation();\n  const queryClient = useQueryClient();\n  const {\n    data,\n    isError,\n    mutateAsync: deleteMemoryMutation,\n  } = useMutation<DeleteMemoryResponse, Error, DeleteMemoryProps>({\n    mutationKey: ['deleteMemory'],\n    mutationFn: async (props) => {\n      const { data: response } = await memoryService.deleteMemory(\n        props.memory_id,\n      );\n      if (response.code !== 0) {\n        throw new Error(response.message || 'Failed to delete memory');\n      }\n\n      queryClient.invalidateQueries({ queryKey: ['memoryList'] });\n      return response;\n    },\n    onSuccess: () => {\n      message.success(t('message.deleted'));\n    },\n    onError: (error) => {\n      message.error(t('message.error', { error: error.message }));\n    },\n  });\n\n  const deleteMemory = useCallback(\n    (props: DeleteMemoryProps) => {\n      return deleteMemoryMutation(props);\n    },\n    [deleteMemoryMutation],","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/web/src/pages/memories/hooks.ts#L156-L192","documentation":"Service-account branch of get_google_creds: the key JSON parsed and creds were built, but after an attempted refresh the credentials still report invalid — Google is rejecting the service-account key itself (deleted key, wrong private key, malformed JSON).","triggerScenarios":"ServiceAccountCredentials.from_service_account_info succeeds structurally but .refresh(Request()) fails (invalid_grant / invalid_signature) and .valid stays False: key deleted in GCP, private_key corrupted by copy-paste, or the JSON is from a different project.","commonSituations":"Key rotated in GCP but old JSON still configured, newlines in the private key mangled by templating/YAML, email field mismatch after project rename.","solutions":["Download a fresh JSON key from GCP > IAM & Admin > Service Accounts > Keys and replace the credential verbatim","Diff the new/old JSON — the private_key must retain its literal \\n escapes; validate with json.loads before saving","Confirm the service account is enabled and the project's Drive API is on"],"exampleFix":"# before: key mangled by YAML templating (real newlines inside private_key)\nsa = {\"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIE...\\n-----END\"}\n\n# after: intact escaped key, verified parseable\nimport json\nsa = json.loads(open('sa-key.json').read())  # use file bytes as-is\nassert \"\\\\n\" in sa[\"private_key\"]  # escaped newlines preserved","handlingStrategy":"try-catch","validationCode":"import json\n\ndef service_account_key_wellformed(json_str: str) -> bool:\n    try:\n        k = json.loads(json_str)\n    except json.JSONDecodeError:\n        return False\n    return (\n        k.get(\"type\") == \"service_account\"\n        and k.get(\"private_key\", \"\").startswith(\"-----BEGIN PRIVATE KEY-----\")\n        and \"\\\\n\" in k[\"private_key\"]\n    )","typeGuard":null,"tryCatchPattern":"from google.oauth2 import service_account\n\ntry:\n    sa = service_account.Credentials.from_service_account_info(\n        json.loads(sa_json), scopes=SCOPES)\n    sa.refresh(Request())          # force validation now, not mid-index\nexcept Exception:\n    raise SystemExit(\"Service-account key rejected — download a fresh JSON from GCP\")","preventionTips":["Paste service-account JSON as downloaded; never re-serialize through YAML/templates","Delete old keys in GCP only after updating the connector credential, not before","Dry-run a cred.refresh() at deploy time to fail fast on bad keys"],"tags":["google-drive","service-account","credentials","authentication"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}