{"record":{"id":"02e5d9a06387f281","repo":"ToolJet/ToolJet","slug":"connection-error-in-salesforce-with-validated-auth","errorCode":null,"errorMessage":"Connection Error in Salesforce with validated auth","messagePattern":"Connection Error in Salesforce with validated auth","errorType":"exception","errorClass":"QueryError","httpStatus":null,"severity":"error","filePath":"marketplace/plugins/salesforce/lib/index.ts","lineNumber":145,"sourceCode":"\n      if (!instanceUrl) {\n        throw new Error('Instance URL is missing from token data in salesforce');\n      }\n\n      const oauth2 = new jsforce.OAuth2({\n        clientId: client_id,\n        clientSecret: client_secret,\n        redirectUri: redirect_uri,\n      });\n\n      const conn = new jsforce.Connection({\n        oauth2: oauth2,\n        instanceUrl: instanceUrl,\n        accessToken: accessToken,\n      });\n      return conn;\n    } catch (error) {\n      throw new QueryError('Connection Error in Salesforce with validated auth', error.message, {});\n    }\n  }\n\n  private getTokenDataFromValidatedSource(sourceOptions: SourceOptions, context): any {\n    if (sourceOptions.tokenData) {\n      if (\n        sourceOptions.multiple_auth_enabled &&\n        Array.isArray(sourceOptions.tokenData) &&\n        sourceOptions.tokenData.length > 0\n      ) {\n        const userTokenData = sourceOptions.tokenData.find((token) => token.user_id === context.user.id);\n        if (!userTokenData) throw new Error('No token data for the particular UserId');\n        if (userTokenData) return userTokenData;\n      } else if (sourceOptions.tokenData) {\n        return sourceOptions.tokenData;\n      }\n    }\n","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/ToolJet/ToolJet/blob/20602a8e101f2e59686c9afde0d1402aac2c8871/marketplace/plugins/salesforce/lib/index.ts#L127-L163","documentation":"The outer catch in getConnectionWithValidatedAuth. It catches anything thrown inside the try — including the 'Instance URL is missing' Error (253), getTokenDataFromValidatedSource Errors (255/256), and any jsforce.Connection constructor failure — and rewraps them as a QueryError with the original message. Because it wraps a QueryError thrown from inside, callers lose the original error class.","triggerScenarios":"Any failure constructing a jsforce.Connection for multi-user OAuth: missing instance_url, missing token data, invalid clientId/secret passed to OAuth2, jsforce throwing on bad arguments.","commonSituations":"Multi-user OAuth path enabled but per-user token data is incomplete. Connected app credentials changed. jsforce version incompatibility throwing in the constructor.","solutions":["Read the description — it carries the inner error's message (e.g., 'instance_url is missing').","Re-authorize the datasource to repopulate all token fields.","Verify getOAuthCredentials returns non-empty client_id/secret/redirect_uri (env vars set for tooljet_app type).","Avoid wrapping QueryError-instances here; rethrow them to preserve the original code."],"exampleFix":"// before\n} catch (error) {\n  throw new QueryError('Connection Error in Salesforce with validated auth', error.message, {});\n}\n\n// after: preserve typed errors\n} catch (error) {\n  if (error instanceof QueryError) throw error;\n  throw new QueryError('Connection Error in Salesforce with validated auth', error.message, { cause: error.message });\n}","handlingStrategy":"try-catch","validationCode":"function validateMultiUserAuthInputs(sourceOptions: any, context: any): void {\n  if (!context?.user?.id) throw new Error('context.user.id required');\n  if (!sourceOptions?.tokenData) throw new Error('tokenData required for multi-user auth');\n}","typeGuard":"import { QueryError } from '@tooljet-marketplace/common';\nfunction isQueryError(e: any): e is QueryError {\n  return e instanceof QueryError;\n}","tryCatchPattern":"try {\n  conn = await plugin.getConnectionWithValidatedAuth(sourceOptions, queryOptions, context);\n} catch (e) {\n  if (e instanceof QueryError && /instance_url|token data/i.test(e.description)) {\n    return { status: 'needs_reconnect', reason: e.description };\n  }\n  throw e;\n}","preventionTips":["Patch the catch to rethrow QueryError instances unchanged so structured codes survive.","Validate tokenData presence and instance_url before entering the try.","Surface the inner error message (it carries the real cause) to operators."],"tags":["salesforce","jsforce","connection","catch-all","multi-user"],"backgroundTag":null,"analyzedSha":"20602a8e101f2e59686c9afde0d1402aac2c8871","analyzedAt":"2026-08-13T05:58:54.221Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}