{"record":{"id":"81886f87a584d8e0","repo":"infiniflow/ragflow","slug":"failed-to-create-search","errorCode":null,"errorMessage":"Failed to create search","messagePattern":"Failed to create search","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/src/pages/next-searches/hooks.ts","lineNumber":53,"sourceCode":"interface CreateSearchResponse {\n  id: string;\n  name: string;\n  description: string;\n}\n\nexport const useCreateSearch = () => {\n  const { t } = useTranslation();\n\n  const {\n    data,\n    isError,\n    mutateAsync: createSearchMutation,\n  } = useMutation<CreateSearchResponse, Error, CreateSearchProps>({\n    mutationKey: ['createSearch'],\n    mutationFn: async (props) => {\n      const { data: response } = await searchService.createSearch(props);\n      if (response.code !== 0) {\n        throw new Error(response.message || 'Failed to create search');\n      }\n      return response.data;\n    },\n    onSuccess: () => {\n      message.success(t('message.created'));\n    },\n    onError: (error) => {\n      message.error(t('message.error', { error: error.message }));\n    },\n  });\n\n  const createSearch = useCallback(\n    (props: CreateSearchProps) => {\n      return createSearchMutation(props);\n    },\n    [createSearchMutation],\n  );\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/web/src/pages/next-searches/hooks.ts#L35-L71","documentation":"_run_with_timeout runs the OAuth helper in a daemon thread and joins with timeout_secs; if the thread is still alive (flow waiting on user consent in a browser) TimeoutError is raised with the given message. This guards headless/automated runs from hanging forever on the consent screen.","triggerScenarios":"Running the interactive local-server OAuth flow (or console fallback) where nobody completes the Google consent page within the timeout — typical in CI, containers, or SSH sessions without browser forwarding.","commonSituations":"Developer runs the token-generation script inside docker/CI, browser opens on the wrong machine, user steps away mid-consent, proxy blocking localhost:8080 callback.","solutions":["Re-run the flow from a machine with a working browser and port-forward localhost if remote (ssh -L 8080:localhost:8080)","Complete the consent screen promptly once the URL appears; close stale tabs from earlier attempts first","For fully headless setups, avoid the interactive flow entirely — use a service-account credential or paste a pre-minted token blob"],"exampleFix":"# before: headless box, nobody clicks consent\ncreds = _run_with_timeout(flow.run_local_server, timeout_secs=300, ...)  # TimeoutError\n\n# after: run on a browser-capable host, or forward the callback port\n# local:$ ssh -L 8080:localhost:8080 ci-host\n# ci-host:$ python scripts/google_oauth_flow.py  # then click through locally","handlingStrategy":"try-catch","validationCode":"import os, socket\n\ndef oauth_flow_env_ok() -> bool:\n    # rough check: can we bind the callback port, is there a display/browser?\n    try:\n        s = socket.socket(); s.bind((\"localhost\", 0)); s.close()\n        return os.environ.get(\"DISPLAY\") is not None or os.environ.get(\"SSH_TUNNEL\") == \"1\"\n    except OSError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    token = run_oauth_with_timeout(flow, timeout_secs=300)\nexcept TimeoutError:\n    # no one completed consent — fall back to pre-minted token, don't loop\n    token = json.loads(get_stored_token_blob())\n    if not token:\n        print(\"Run the flow from a machine with a browser (ssh -L 8080:localhost:8080).\")","preventionTips":["Run interactive OAuth only from a desktop session; use ssh -L for remote hosts","Raise timeout_secs generously for first-time consents","Keep a pre-minted token blob as the fallback for headless re-runs"],"tags":["google-oauth","timeout","headless","browser","credentials"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}