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
- 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
- If providing only a client config, structure it as {'installed': {...}} or {'web': {...}} so ensure_oauth_token_dict can drive the flow
- 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
- Generate tokens once in a browser-capable environment and reuse the blob
- Never run the interactive flow from long-lived server processes; pre-mint instead
- Script a shape check (is_complete_oauth_blob) at credential-save time
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
- main() returned a non-JSON-serializable value.
- message.compileNotSupported
- Failed to update memory
- main() must return a value. Use null for an empty result.
- Failed to read compilation status
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/e17c2005113855e2.
Report an issue: GitHub.