infiniflow/ragflow · error · Error

Failed to fetch search list

Error message

Failed to fetch search list

What it means

google_auth_oauthlib emits a Warning('Scope has changed') when the scopes requested at run time differ from those previously granted/consented — practically, Google refused one of the requested scopes. This handler converts it into a RuntimeError with concrete remediation: add the scopes in the consent screen or override the requested set via GOOGLE_OAUTH_SCOPE_OVERRIDE.

Source

Thrown at web/src/pages/next-searches/hooks.ts:137

        filterValue,
        ...pagination,
      },
    ],
    queryFn: async () => {
      const { data: response } = await searchService.getSearchList(
        {
          params: {
            keywords: debouncedSearchString,
            page_size: pagination.pageSize,
            page: pagination.current,
            owner_ids: filterValue.owner,
          },
          paramsSerializer: { indexes: null },
        },
        true,
      );
      if (response.code !== 0) {
        throw new Error(response.message || 'Failed to fetch search list');
      }
      return response;
    },
  });

  return {
    data,
    isLoading,
    isError,
    pagination,
    searchString,
    handleInputChange,
    setPagination,
    refetch,
    filterValue,
    handleFilterSubmit,
  };
};

View on GitHub (pinned to 554fb1133a)

Solutions

  1. GCP Console > APIs & Services > OAuth consent screen: add the Drive metadata and Admin Directory read scopes, then re-run the flow
  2. If policy blocks those scopes, set GOOGLE_OAUTH_SCOPE_OVERRIDE=<comma-separated allowed scopes> and re-run — accept the reduced functionality
  3. For testing apps in testing status, add your test users so scope grants succeed

Example fix

# before: flow requests fixed scopes the app can't grant
scopes = _get_requested_scopes(source)  # includes admin.directory...
flow.run_local_server(scopes=scopes)  # Warning → RuntimeError

# after: restrict to permitted scopes via env
# export GOOGLE_OAUTH_SCOPE_OVERRIDE="https://www.googleapis.com/auth/drive.readonly.metadata"
flow.run_local_server()  # _get_requested_scopes honors the override
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED_FLOW_SCOPES = {
    "https://www.googleapis.com/auth/drive.readonly.metadata",
    "https://www.googleapis.com/auth/admin.directory.user.readonly",
}

def consent_screen_covers_required() -> bool:
    configured = fetch_oauth_app_scopes()  # via GCP API or config export
    return REQUIRED_FLOW_SCOPES <= configured or bool(os.environ.get("GOOGLE_OAUTH_SCOPE_OVERRIDE"))

Try / catch

try:
    token_dict = run_google_oauth_flow(source)
except RuntimeError as e:
    if "Scope has changed" in str(e) or "requested OAuth scopes" in str(e):
        os.environ["GOOGLE_OAUTH_SCOPE_OVERRIDE"] = ask_admin_for_allowed_scopes()
        token_dict = run_google_oauth_flow(source)  # retry with reduced set
    else:
        raise

Prevention

When it happens

Trigger: Running the OAuth flow requesting Drive metadata + Admin Directory read scopes when the GCP app's configured consent screen does not include them (unverified app scope restrictions, internal-only app missing scope registration), or Google's default run_local_server behavior detecting a scope delta.

Common situations: New deployments where the OAuth consent screen was never updated with the admin-directory scope, Workspace policies restricting sensitive scopes until the app is verified, custom scope lists diverging from what was consented previously.

Related errors


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