{"record":{"id":"4b3f10f228eceaa8","repo":"infiniflow/ragflow","slug":"failed-to-read-compilation-status","errorCode":null,"errorMessage":"Failed to read compilation status","messagePattern":"Failed to read compilation status","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"web/src/hooks/use-dataset-generate.ts","lineNumber":123,"sourceCode":"    retryDelay: 1000,\n    enabled: open && !!id,\n    queryFn: async () => {\n      if (isGoDatasetBackend()) {\n        // Scheduler compile-status contract (dataset-level, variant-agnostic).\n        // The status is NOT a task percentage: we carry the raw state, the\n        // MySQL inflight/backlog entry counts and the error diagnostic, and\n        // derive the display status in useGenerateStatus. progress is only set\n        // so the shared refetch/status helpers keep their contract (idle->0,\n        // running/pending->0, completed->1, error->0).\n        const res = await getDatasetCompilationStatus(id!);\n        const data = res?.data;\n        // The handler returns HTTP 200 with a non-zero business code for\n        // authorization/business errors (e.g. \"no authorization\"). The request\n        // interceptor only shows a toast and does not reject, so without this\n        // explicit check a failed read would be mapped to a misleading idle\n        // state. Reject so the query surfaces the error instead.\n        if (!data || data.code !== 0) {\n          throw new Error(data?.message || 'Failed to read compilation status');\n        }\n        const st = data.data ?? {};\n        const state: string = st.state ?? 'idle';\n        const error: string = st.error ?? '';\n        return {\n          progress: state === 'completed' ? 1 : state === 'idle' ? 0 : 0,\n          progress_msg: error || state,\n          compilationState: state,\n          inflight: st.inflight ?? 0,\n          backlog: st.backlog ?? 0,\n          compilationError: error,\n        } as ITraceInfo;\n      }\n      const { data } = await traceIndex(id!, traceType);\n      return data?.data ?? {};\n    },\n  });\n};","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/web/src/hooks/use-dataset-generate.ts#L105-L141","documentation":"validate_connector_settings bails out when self._creds is None — load_credentials() was never called (or failed before assigning creds) yet settings validation was invoked. ConnectorMissingCredentialError signals the lifecycle mistake to the caller/UI.","triggerScenarios":"Constructing GoogleDriveConnector and calling validate_connector_settings() directly without load_credentials(), or load_credentials raising earlier (e.g. error 627's missing-key ValueError) leaving _creds unset while the caller still proceeds to validate.","commonSituations":"UI 'Test connection' pressed before the credential JSON is saved, a previous load_credentials failure swallowed by an except-pass block, perm-sync job scheduled on a half-configured connector.","solutions":["Call load_credentials(creds_dict) successfully before validate_connector_settings()","Fix the underlying credential payload error (missing primary admin key, malformed token JSON) that prevented _creds from being set","Order operations: construct → load_credentials → validate_connector_settings → index"],"exampleFix":"# before\nconnector = GoogleDriveConnector(...)\nconnector.validate_connector_settings()  # boom\n\n# after\nconnector = GoogleDriveConnector(...)\nconnector.load_credentials(credentials_dict)\nconnector.validate_connector_settings()","handlingStrategy":"validation","validationCode":"def validate_ready(connector) -> bool:\n    return connector._creds is not None  # via load_credentials having run","typeGuard":null,"tryCatchPattern":"from common.data_source.exceptions import ConnectorMissingCredentialError\n\ntry:\n    connector.validate_connector_settings()\nexcept ConnectorMissingCredentialError:\n    connector.load_credentials(load_credential_from_db(conn_id))\n    connector.validate_connector_settings()","preventionTips":["In UI flows, disable 'Test connection' until a credential is saved","Never swallow exceptions from load_credentials; treat partial load as failure","Keep a single factory that wires construct+load so callers can't skip a step"],"tags":["google-drive","lifecycle","credentials","connector"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}