FlowiseAI/Flowise · critical · Error

Disallowed TypeORM DataSource option: ${key}

Error message

Disallowed TypeORM DataSource option: ${key}

What it means

sanitizeDataSourceOptions rejects any config containing a key in BLOCKED_DATASOURCE_KEYS = ['entities','subscribers','migrations','extra']. These TypeORM DataSource options accept file paths that TypeORM dynamically imports/executes during DataSource.initialize(), so accepting them from user input is an arbitrary-code-execution vector. The guard throws the moment any blocked key is present, before the config reaches TypeORM.

Source

Thrown at packages/components/src/sanitizeDataSourceOptions.ts:23

/** Connection options that must be set by the node, not via additionalConfig. */
const RESERVED_CONNECTION_KEYS = ['database', 'type', 'url', 'host', 'port', 'username', 'password'] as const

export type BlockedDataSourceKey = (typeof BLOCKED_DATASOURCE_KEYS)[number]
export type ReservedConnectionKey = (typeof RESERVED_CONNECTION_KEYS)[number]

/**
 * Rejects user-supplied TypeORM DataSource options that can lead to arbitrary code execution
 * when passed to `new DataSource(options).initialize()`.
 */
export function sanitizeDataSourceOptions(config: ICommonObject): ICommonObject {
    if (!config || typeof config !== 'object' || Array.isArray(config)) {
        return {}
    }

    for (const key of BLOCKED_DATASOURCE_KEYS) {
        if (key in config) {
            throw new Error(`Disallowed TypeORM DataSource option: ${key}`)
        }
    }

    return { ...config }
}

/**
 * Rejects user-supplied connection fields that must not override node-controlled settings.
 */
export function rejectReservedDataSourceKeys(config: ICommonObject): void {
    if (!config || typeof config !== 'object' || Array.isArray(config)) {
        return
    }

    for (const key of RESERVED_CONNECTION_KEYS) {
        if (key in config) {
            throw new Error(`Disallowed TypeORM DataSource option: ${key}`)
        }

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Remove 'entities', 'subscribers', 'migrations', and 'extra' from the user-supplied config.
  2. If entity/migration loading is genuinely required, it must be controlled by the node implementation, never passed through user input.
  3. Validate config keys against an allowlist before calling sanitizeDataSourceOptions to fail earlier with a clearer message.

Example fix

// before: user config triggers ACE-prevention guard
sanitizeDataSourceOptions({ type: 'postgres', entities: ['src/entity/*.js'] }) // throws

// after: drop blocked keys; entities are node-controlled
sanitizeDataSourceOptions({ type: 'postgres', schema: 'public' })
Defensive patterns

Strategy: validation

Validate before calling

const BLOCKED = ['entities', 'subscribers', 'migrations', 'extra'] as const

function stripBlockedDataSourceKeys<T extends Record<string, unknown>>(cfg: T): T {
  const out: any = { ...cfg }
  for (const k of BLOCKED) delete out[k]
  return out
}

Type guard

const hasNoBlockedDataSourceKeys = (cfg: unknown): boolean =>
  !!cfg && typeof cfg === 'object' &&
  !['entities', 'subscribers', 'migrations', 'extra'].some((k) => k in (cfg as object))

Try / catch

try {
  return sanitizeDataSourceOptions(userConfig)
} catch (e) {
  throw new Error(`Rejected user datasource config: ${(e as Error).message}. Remove entities/subscribers/migrations/extra.`, { cause: e })
}

Prevention

When it happens

Trigger: User-supplied additionalOptions/credentialOptions JSON includes 'entities', 'subscribers', 'migrations', or 'extra' (e.g. 'entities': ['./*.entity.js']).

Common situations: Pasting a TypeORM tutorial connection snippet that lists entities/migrations; migrating from a standalone TypeORM app config into Flowise's additionalOptions field; attempting to point TypeORM at custom entity files.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/334a4b3519f67f46. Report an issue: GitHub.