FlowiseAI/Flowise · error · Error

Invalid SQLite path: path must be within allowed directories

Error message

Invalid SQLite path: path must be within allowed directories (${allowedDirs.join(', ')}). Attempted path: ${resolvedPath}

What it means

Thrown by validateSQLitePath (packages/components/src/validator.ts:353) when the resolved absolute path is not inside any allowed base directory. Allowed dirs are ~/.flowise plus DATABASE_PATH (if set). The message names the allowed dirs and the attempted path.

Source

Thrown at packages/components/src/validator.ts:353

    const basePath = userProvidedPath.trim()

    if (basePath.includes('..')) throw new Error('Invalid SQLite path: path traversal attempt detected')
    if (basePath.toLowerCase().includes('%2e') || basePath.toLowerCase().includes('%2f') || basePath.toLowerCase().includes('%5c'))
        throw new Error('Invalid SQLite path: encoded path traversal attempt detected')
    // eslint-disable-next-line no-control-regex
    if (/\0/.test(basePath) || /[\x00-\x1f]/.test(basePath))
        throw new Error('Invalid SQLite path: null bytes or control characters detected')
    if (/^[a-zA-Z]:\\/.test(basePath)) throw new Error('Invalid SQLite path: Windows absolute paths are not allowed')
    if (/^\\\\[^\\]/.test(basePath)) throw new Error('Invalid SQLite path: UNC paths are not allowed')
    if (/^\\\\\?\\/.test(basePath)) throw new Error('Invalid SQLite path: extended-length paths are not allowed')

    const resolvedPath = path.isAbsolute(basePath) ? path.resolve(basePath) : path.resolve(path.join(defaultDir, basePath))

    if (resolvedPath.includes('..')) throw new Error('Invalid SQLite path: path traversal detected in resolved path')

    if (!isPathWithinAllowedSQLiteDirs(resolvedPath, allowedDirs)) {
        throw new Error(
            `Invalid SQLite path: path must be within allowed directories (${allowedDirs.join(', ')}). Attempted path: ${resolvedPath}`
        )
    }

    return resolvedPath
}

/**
 * Restricts SQL executed against a SQLite database opened via validateSQLitePath to a
 * single read-only SELECT/WITH statement.
 *
 * The Sql Database Chain hands LLM-generated SQL directly to TypeORM's raw query
 * executor with no statement-type filtering. Without this guard, a compromised or
 * malicious LLM response can run `ATTACH DATABASE`/`VACUUM INTO`/bare `PRAGMA` to write
 * arbitrary files anywhere the process can write, bypassing validateSQLitePath (which
 * only constrains the initial connection path, not queries run afterward).
 *
 * All legitimate queries issued against sqlite by this chain (including langchain's own

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Set DATABASE_PATH=/your/data/dir and place the file inside it.
  2. Use a relative filename to resolve automatically under ~/.flowise.
  3. Confirm HOME / USERPROFILE is set correctly — getUserHome() drives the allow-list root.
  4. Symlink the target dir into ~/.flowise and use a relative filename.

Example fix

// before
process.env.DATABASE_PATH = ''
nodeParams.databasePath = '/mnt/data/app.db'

// after
process.env.DATABASE_PATH = '/mnt/data'
nodeParams.databasePath = '/mnt/data/app.db'   // inside allow-list
Defensive patterns

Strategy: validation

Validate before calling

const { resolve, join } = require('path');
const allowed = [join(require('os').homedir(), '.flowise')];
if (process.env.DATABASE_PATH) allowed.push(resolve(process.env.DATABASE_PATH));
const r = resolve(databasePath);
if (!allowed.some((d) => r === d || r.startsWith(d + require('path').sep))) throw new Error('DB path outside allow-list: ' + r);

Type guard

const isWithinAllowed = (p: string, allowed: string[]): p is string => allowed.some((d) => p === d || p.startsWith(d + '/'));

Try / catch

try { validateSQLitePath(databasePath) } catch (e) { if (e instanceof Error && /within allowed directories/.test(e.message)) { throw new Error('set DATABASE_PATH or move DB under ~/.flowise') } else throw e }

Prevention

When it happens

Trigger: Database Path resolves outside ~/.flowise (and outside DATABASE_PATH when unset), e.g. '/var/lib/flowise.db', '/tmp/x.sqlite', or a relative path that escapes via a symlink.

Common situations: Wanting the DB on a separate volume; Docker mounts outside the default dir; production deployments needing a custom data dir; HOME pointing somewhere unexpected.

Related errors


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