OtterMind/Chat2DB · error · NeedLoggedInBusinessException

common.needLoggedIn

common.needLoggedIn

Error message

common.needLoggedIn

What it means

NeedLoggedInBusinessException ('common.needLoggedIn') is raised in decryptSensitiveFields when a non-local datasource needs RSA decryption but the request Context is missing or has no organizationToken. Without the org token the private key needed to decrypt host/url/user/password cannot be derived.

Source

Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbWorkspaceDataSourceServiceImpl.java:207

        } catch (BeanInstantiationException exception) {
            log.debug("Cannot preserve workspace datasource subtype {}.", dataSource.getClass().getName(), exception);
            copy = new WorkspaceDataSource();
        }
        BeanUtils.copyProperties(dataSource, copy);
        return copy;
    }

    private void decryptSensitiveFields(WorkspaceDataSource dataSource) {
        if (dataSource == null) {
            return;
        }
        if ("LOCAL".equalsIgnoreCase(dataSource.getStorageType()) || ConfigUtils.isLocalPersistence()) {
            dataSource.setPassword(decryptString(dataSource.getPassword()));
            return;
        }
        Context context = ContextUtils.queryContext();
        if (context == null || context.getOrganizationToken() == null) {
            throw new NeedLoggedInBusinessException();
        }
        PrivateKey privateKey = stringToPrivateKey(context.getOrganizationToken());
        if (StringUtils.isNotBlank(dataSource.getPassword())) {
            dataSource.setPassword(decryptToken(dataSource.getPassword(), privateKey));
        }
        if (StringUtils.isNotBlank(dataSource.getHost())) {
            dataSource.setHost(decryptToken(dataSource.getHost(), privateKey));
        }
        if (StringUtils.isNotBlank(dataSource.getUrl())) {
            dataSource.setUrl(decryptToken(dataSource.getUrl(), privateKey));
        }
        if (StringUtils.isNotBlank(dataSource.getUser())) {
            dataSource.setUser(decryptToken(dataSource.getUser(), privateKey));
        }
    }

    private PrivateKey stringToPrivateKey(String privateKeyString) {
        try {

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Ensure the client re-authenticates so a valid organization token populates the request context before listing/exporting datasources.
  2. Verify the auth filter/interceptor that sets Context.organizationToken is registered and runs before this service.
  3. If this deployment stores datasources locally, confirm storageType is 'LOCAL' or ConfigUtils.isLocalPersistence() is true so the RSA path is skipped.

Example fix

// before: caller does not ensure auth
List<WorkspaceDataSource> out = svc.exportDisplayDataSources(ids);
// after: caller guarantees a logged-in context first
if (ContextUtils.queryContext() == null || ContextUtils.queryContext().getOrganizationToken() == null) {
    throw new NeedLoggedInBusinessException();
}
List<WorkspaceDataSource> out = svc.exportDisplayDataSources(ids);
Defensive patterns

Strategy: validation

Validate before calling

Context ctx = ContextUtils.queryContext();
boolean needsOrgToken = !("LOCAL".equalsIgnoreCase(ds.getStorageType()) || ConfigUtils.isLocalPersistence());
if (needsOrgToken && (ctx == null || ctx.getOrganizationToken() == null)) {
    throw new NeedLoggedInBusinessException();
}

Prevention

When it happens

Trigger: Reading/decoding a CLOUD-stored datasource (storageType != 'LOCAL' and not ConfigUtils.isLocalPersistence()) on a request whose ContextUtils.queryContext() returns null or context.getOrganizationToken() is null — typically an unauthenticated or session-expired API call.

Common situations: Session expired mid-use; API call missing the auth header that populates the context; misconfigured environment where local-persistence flag is off but no org-token provider is wired; exportDisplayDataSources called without a logged-in user.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/8a4f92ad293da0a3. Report an issue: GitHub.