infiniflow/ragflow · error · Error

Failed to update memory

Error message

Failed to update memory

What it means

Terminal fallback in get_google_creds: neither the OAuth branch produced oauth_creds nor did the service-account branch produce service_creds. The credential dict matched no recognized structure (no token key, no service-account key, or both branches failed silently earlier), so the app cannot guess how to authenticate.

Source

Thrown at web/src/pages/memories/hooks.ts:211

  );

  return { data, isError, deleteMemory };
};

export const useUpdateMemory = () => {
  const { t } = useTranslation();
  const queryClient = useQueryClient();
  const {
    data,
    isError,
    mutateAsync: updateMemoryMutation,
  } = useMutation<any, Error, IMemoryAppDetailProps>({
    mutationKey: ['updateMemory'],
    mutationFn: async (formData) => {
      const param = omit(formData, ['id']);
      const { data: response } = await updateMemoryById(formData.id, param);
      if (response.code !== 0) {
        throw new Error(response.message || 'Failed to update memory');
      }

      return response.data;
    },
    onSuccess: (data, variables) => {
      message.success(t('message.updated'));
      queryClient.invalidateQueries({
        queryKey: ['memoryDetail', variables.id],
      });
      queryClient.invalidateQueries({
        queryKey: [MemoryApiAction.FetchMemoryDetail],
      });
    },
  });

  const updateMemory = useCallback(
    (formData: IMemoryAppDetailProps) => {
      return updateMemoryMutation(formData);

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Inspect the credential dict keys and compare against what get_google_creds expects: token-dict key (with client_id/secret/refresh_token) or service-account key
  2. Rebuild the credential from a known-good source: OAuth flow output or GCP-downloaded service-account JSON
  3. Check for earlier swallowed exceptions in the OAuth/service-account branches — this error is often a downstream symptom

Example fix

# before
credentials = {"username": "x", "password": "y"}
get_google_creds(credentials, source)  # unknown structure

# after
credentials = {
    "google_drive_token_dict": '{"client_id": "...", "client_secret": "...", "refresh_token": "..."}',
    "primary_admin_email": "admin@acme.com",
}
get_google_creds(credentials, source)
Defensive patterns

Strategy: validation

Validate before calling

def recognized_google_credential(creds: dict) -> str | None:
    if DB_CREDENTIALS_DICT_TOKEN_KEY in creds and creds[DB_CREDENTIALS_DICT_TOKEN_KEY]:
        return "oauth"
    if DB_CREDENTIALS_DICT_SERVICE_ACCOUNT_KEY in creds and creds[DB_CREDENTIALS_DICT_SERVICE_ACCOUNT_KEY]:
        return "service_account"
    return None

Try / catch

try:
    creds_obj, new_dict = get_google_creds(credentials, source)
except PermissionError as e:
    if "unknown credential structure" in str(e):
        raise ConfigurationError(
            "Credential needs either an OAuth token blob or a service-account key; "
            f"found keys: {sorted(credentials)}"
        ) from e

Prevention

When it happens

Trigger: Credential payload contains unrelated keys (e.g. only a username/password pair), the token key present but empty string, or both branches raising before assignment in an environment that swallows the earlier errors.

Common situations: Credential written for a different connector type, fields stripped by a sanitizer, dict built with None values from an empty form.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/1c60b3847ecfc340. Report an issue: GitHub.