abhigyanpatwari/GitNexus · error
Invalid DuckDB extension name: ${extensionName}
Error message
Invalid DuckDB extension name: ${extensionName} What it means
installDuckDbExtensionOutOfProcess() in gitnexus/src/core/lbug/extension-loader.ts validates the extension name against /^[A-Za-z][A-Za-z0-9_]*$/ before spawning the child process that runs the DuckDB INSTALL. The guard keeps arbitrary strings out of the child's environment and the INSTALL statement (injection safety). Names must start with a letter and contain only letters, digits, and underscores — no hyphens, dots, version suffixes, or file extensions.
Source
Thrown at gitnexus/src/core/lbug/extension-loader.ts:135
const childScript = new URL('../../../scripts/install-duckdb-extension.mjs', import.meta.url);
return [fileURLToPath(childScript), extensionName, String(maxDbSize)];
};
/**
* Run `INSTALL <extension>` in a short-lived child Node process so the parent
* event loop is never blocked by DuckDB's synchronous network call.
*
* The child opens its own scratch LadybugDB, executes the install, and exits.
* If the child exceeds `timeoutMs` the parent kills it with SIGKILL and
* resolves with `timedOut: true`.
*/
export const installDuckDbExtensionOutOfProcess = async (
extensionName: string,
timeoutMs: number = getExtensionInstallTimeoutMs(),
loadError?: string,
): Promise<ExtensionInstallResult> => {
if (!EXTENSION_NAME_PATTERN.test(extensionName)) {
throw new Error(`Invalid DuckDB extension name: ${extensionName}`);
}
return await new Promise<ExtensionInstallResult>((resolve) => {
const child = spawn(process.execPath, getExtensionInstallChildProcessArgs(extensionName), {
env: {
...process.env,
GITNEXUS_LBUG_EXTENSION_NAME: extensionName,
// The child picks INSTALL vs FORCE INSTALL from this LOAD error so it
// only re-downloads when the on-disk extension file is actually broken.
...(loadError ? { GITNEXUS_LBUG_EXTENSION_LOAD_ERROR: loadError } : {}),
},
stdio: ['ignore', 'ignore', 'pipe'],
windowsHide: true,
});
let stderr = '';
child.stderr?.setEncoding('utf8');
child.stderr?.on('data', (chunk) => {View on GitHub (pinned to aac7515d2a)
Solutions
- Use the bare extension identifier: letters/digits/underscore only, starting with a letter (e.g. "icu", "fts", "parquet")
- Strip version suffixes (@vX.Y.Z) and file extensions (.duckdb_extension, .wasm) from configured names
- Fix the offending entry in the extension configuration that feeds installDuckDbExtensionOutOfProcess
Example fix
# before GITNEXUS_LBUG_EXTENSION_NAME="icu.duckdb_extension" # after GITNEXUS_LBUG_EXTENSION_NAME="icu"
Defensive patterns
Strategy: validation
Validate before calling
const EXTENSION_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]*$/;
const name = rawName.trim().replace(/\.duckdb_extension(\.wasm)?$/, '').split('@')[0];
if (!EXTENSION_NAME_PATTERN.test(name)) {
throw new TypeError(`Unsupported extension name: ${rawName} (normalized: ${name})`);
}
await installDuckDbExtensionOutOfProcess(name); Type guard
function isValidDuckDbExtensionName(name: unknown): name is string {
return typeof name === 'string' && /^[A-Za-z][A-Za-z0-9_]*$/.test(name);
} Try / catch
try {
await installDuckDbExtensionOutOfProcess(name, timeoutMs);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Invalid DuckDB extension name')) {
// fix the configured name (strip suffixes/hyphens); this is deterministic, never retry as-is
}
throw err;
} Prevention
- Validate extension names once where they are configured (load-time assert), not at install time
- Keep a curated list of known-good extension identifiers and reject anything outside it in config validation
When it happens
Trigger: Requesting an out-of-process install of a name like "full-text" (hyphen), "icu.duckdb_extension", "fts@v1.1.0", "42fts" (leading digit), or an empty string — typically from a lbug extensions config entry or env override that copied the DuckDB catalog name verbatim.
Common situations: Copying extension identifiers from DuckDB documentation or marketplace URLs (which include version suffixes and file names); config drift after renaming an internal extension; hand-edited settings files.
Related errors
- Invalid DuckDB extension name: ${name}
- withRetry: maxAttempts must be >= 1, got ${opts.maxAttempts}
- FTS extension unavailable - cannot create FTS index ${tableN
- FTS index '${indexName}' on table ${tableName} exists but th
- Structural relationship count failed; the graph-write-collap
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/aa8daf4640d1e61d.
Report an issue: GitHub.