infiniflow/ragflow · error · Error

Failed to fetch memory detail

Error message

Failed to fetch memory detail

What it means

In get_google_creds, when the stored token JSON lacks client_id/client_secret/refresh_token the code tries ensure_oauth_token_dict to regenerate tokens from a client secret; when that also fails (no usable client config, flow error) a PermissionError is raised telling the user to finish the OAuth flow.

Source

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

    id: memoryId,
  };
  if (shared_id) {
    param = {
      id: memoryId,
      tenant_id: tenantId,
    };
  }
  const fetchMemoryDetailFunc = shared_id
    ? memoryService.getMemoryDetailShare
    : memoryService.getMemoryDetail;

  const { data, isLoading, isError } = useQuery<MemoryDetailResponse, Error>({
    queryKey: ['memoryDetail', memoryId],
    enabled: !shared_id || !!tenantId,
    queryFn: async () => {
      const { data: response } = await fetchMemoryDetailFunc(param);
      if (response.code !== 0) {
        throw new Error(response.message || 'Failed to fetch memory detail');
      }
      return response;
    },
  });

  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) => {

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Run the standalone OAuth flow (scripts/google_oauth_flow or equivalent) to mint a complete {client_id, client_secret, refresh_token} blob and paste that as the credential
  2. If providing only a client config, structure it as {'installed': {...}} or {'web': {...}} so ensure_oauth_token_dict can drive the flow
  3. Never hand-trim fields out of a working token JSON

Example fix

# before: pasted client_secret.json
{ "installed": {"client_id": "...", "client_secret": "..."} }
# with fields flattened away → incomplete token dict

# after: complete token blob from a finished flow
{ "client_id": "...", "client_secret": "...",
  "refresh_token": "1//0e...", "token_uri": "..." }
Defensive patterns

Strategy: validation

Validate before calling

def is_complete_oauth_blob(d: dict) -> bool:
    return all(k in d for k in ("client_id", "client_secret", "refresh_token"))

def oauth_blob_or_runnable_flow(d: dict) -> bool:
    return is_complete_oauth_blob(d) or "installed" in d or "web" in d

Type guard

def has_installed_client_config(d: dict) -> bool:
    return isinstance(d.get("installed"), dict) or isinstance(d.get("web"), dict)

Try / catch

try:
    creds, new_dict = get_google_creds(credentials, source)
except PermissionError as e:
    if "finish the OAuth flow" in str(e):
        credentials["google_drive_tokens"] = json.dumps(run_oauth_flow_headless_safe())
        creds, new_dict = get_google_creds(credentials, source)

Prevention

When it happens

Trigger: Credential dict contains a token blob with only an access token or only a client_secret.json-style fragment without 'installed'/'web' keys; or ensure_oauth_token_dict raises because the interactive flow cannot run in a headless server process.

Common situations: Pasting a client_secret.json downloaded from GCP directly into the token field (no 'installed' wrapper key), partial manual token edits, running the connector in a container where the local-server OAuth flow cannot open a browser.

Related errors


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