diff --git a/packages/components/credentials/GoogleSheetsOAuth2.credential.ts b/packages/components/credentials/GoogleSheetsOAuth2.credential.ts index 3e21479224f..259bfc31747 100644 --- a/packages/components/credentials/GoogleSheetsOAuth2.credential.ts +++ b/packages/components/credentials/GoogleSheetsOAuth2.credential.ts @@ -1,5 +1,6 @@ import { INodeParams, INodeCredential } from '../src/Interface' const scopes = [ + 'https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive.metadata' diff --git a/packages/ui/src/views/docstore/LoaderConfigPreviewChunks.jsx b/packages/ui/src/views/docstore/LoaderConfigPreviewChunks.jsx index 660571ff358..f32fa7179ad 100644 --- a/packages/ui/src/views/docstore/LoaderConfigPreviewChunks.jsx +++ b/packages/ui/src/views/docstore/LoaderConfigPreviewChunks.jsx @@ -31,7 +31,7 @@ import documentStoreApi from '@/api/documentstore' import documentsApi from '@/api/documentstore' // Const -import { baseURL, gridSpacing } from '@/store/constant' +import { baseURL, gridSpacing, FLOWISE_CREDENTIAL_ID } from '@/store/constant' import { closeSnackbar as closeSnackbarAction, enqueueSnackbar as enqueueSnackbarAction } from '@/store/actions' import { useError } from '@/store/context/ErrorContext' @@ -147,7 +147,7 @@ const LoaderConfigPreviewChunks = () => { if ( inputParam.type === 'credential' && !selectedDocumentLoader.credential && - !selectedDocumentLoader.inputs['FLOWISE_CREDENTIAL_ID'] + !selectedDocumentLoader.inputs[FLOWISE_CREDENTIAL_ID] ) { canSubmit = false missingFields.push(inputParam.label || inputParam.name) @@ -317,6 +317,18 @@ const LoaderConfigPreviewChunks = () => { nodeData.credential = existingLoaderFromDocStoreTable.credential setLoaderName(existingLoaderFromDocStoreTable.loaderName) } + // Restore credential from the separate `credential` field on the loader entity. + // This block intentionally runs outside the loaderConfig guard above because + // `loader.credential` is persisted as its own DB column — independent of + // loaderConfig — and may be the *only* place the credential ID is stored for + // loaders created before FLOWISE_CREDENTIAL_ID was written into inputs. + // Without this, checkMandatoryFields and prepareConfig both miss the credential, + // causing a false "Connect Credential" validation error on process/preview. + if (existingLoaderFromDocStoreTable?.credential) { + nodeData.credential = existingLoaderFromDocStoreTable.credential + if (!nodeData.inputs) nodeData.inputs = {} + nodeData.inputs[FLOWISE_CREDENTIAL_ID] = existingLoaderFromDocStoreTable.credential + } setSelectedDocumentLoader(nodeData) // Check if the loader has a text splitter, if yes, get the text splitter nodes