infiniflow/ragflow · error · Error
Failed to delete memory
Error message
Failed to delete memory
What it means
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).
Source
Thrown at web/src/pages/memories/hooks.ts:174
return { data: data?.data, isLoading, isError };
};
export const useDeleteMemory = () => {
const { t } = useTranslation();
const queryClient = useQueryClient();
const {
data,
isError,
mutateAsync: deleteMemoryMutation,
} = useMutation<DeleteMemoryResponse, Error, DeleteMemoryProps>({
mutationKey: ['deleteMemory'],
mutationFn: async (props) => {
const { data: response } = await memoryService.deleteMemory(
props.memory_id,
);
if (response.code !== 0) {
throw new Error(response.message || 'Failed to delete memory');
}
queryClient.invalidateQueries({ queryKey: ['memoryList'] });
return response;
},
onSuccess: () => {
message.success(t('message.deleted'));
},
onError: (error) => {
message.error(t('message.error', { error: error.message }));
},
});
const deleteMemory = useCallback(
(props: DeleteMemoryProps) => {
return deleteMemoryMutation(props);
},
[deleteMemoryMutation],View on GitHub (pinned to 554fb1133a)
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
Example fix
# before: key mangled by YAML templating (real newlines inside private_key)
sa = {"private_key": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END"}
# after: intact escaped key, verified parseable
import json
sa = json.loads(open('sa-key.json').read()) # use file bytes as-is
assert "\\n" in sa["private_key"] # escaped newlines preserved Defensive patterns
Strategy: try-catch
Validate before calling
import json
def service_account_key_wellformed(json_str: str) -> bool:
try:
k = json.loads(json_str)
except json.JSONDecodeError:
return False
return (
k.get("type") == "service_account"
and k.get("private_key", "").startswith("-----BEGIN PRIVATE KEY-----")
and "\\n" in k["private_key"]
) Try / catch
from google.oauth2 import service_account
try:
sa = service_account.Credentials.from_service_account_info(
json.loads(sa_json), scopes=SCOPES)
sa.refresh(Request()) # force validation now, not mid-index
except Exception:
raise SystemExit("Service-account key rejected — download a fresh JSON from GCP") Prevention
- 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
When it happens
Trigger: 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.
Common situations: Key rotated in GCP but old JSON still configured, newlines in the private key mangled by templating/YAML, email field mismatch after project rename.
Related errors
- Failed to update memory
- main() must be defined or exported.
- main() returned a non-JSON-serializable value.
- Failed to read compilation status
- message.compileNotSupported
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/2ecf39fd80ff00af.
Report an issue: GitHub.