paperclipai/paperclip · error

Config at ${configPath} does not define a database connectio

Error message

Config at ${configPath} does not define a database connection string.

What it means

Thrown by openConfiguredDb() in the non-embedded branch when `nonEmpty(config.database.connectionString)` is falsy. The config exists but its database block omits a connection string while not using embedded-postgres mode, so there is no way to reach the database.

Source

Thrown at cli/src/commands/routines.ts:216

      const adminConnectionString = `postgres://paperclip:paperclip@127.0.0.1:${embeddedHandle.port}/postgres`;
      await ensurePostgresDatabase(adminConnectionString, "paperclip");
      const connectionString = `postgres://paperclip:paperclip@127.0.0.1:${embeddedHandle.port}/paperclip`;
      await applyPendingMigrations(connectionString);
      const db = createDb(connectionString) as ClosableDb;
      return {
        db,
        stop: async () => {
          await closeDb(db);
          if (embeddedHandle?.startedByThisProcess) {
            await embeddedHandle.stop().catch(() => undefined);
          }
        },
      };
    }

    const connectionString = nonEmpty(config.database.connectionString);
    if (!connectionString) {
      throw new Error(`Config at ${configPath} does not define a database connection string.`);
    }

    await applyPendingMigrations(connectionString);
    const db = createDb(connectionString) as ClosableDb;
    return {
      db,
      stop: async () => {
        await closeDb(db);
      },
    };
  } catch (error) {
    if (embeddedHandle?.startedByThisProcess) {
      await embeddedHandle.stop().catch(() => undefined);
    }
    throw error;
  }
}

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Add a non-empty `database.connectionString` to your config file.
  2. Or switch `database.mode` to `embedded-postgres` if you want the bundled DB instead.
  3. Confirm the connection string is not sourced from an unset environment variable.

Example fix

// before
{ "database": { "mode": "postgres" } }
// after
{ "database": { "mode": "postgres", "connectionString": "postgres://user:pass@host:5432/db" } }
Defensive patterns

Strategy: validation

Validate before calling

function assertConnectionString(config: {database: {mode: string; connectionString?: string}}, path: string): void {
  if (config.database.mode !== 'embedded-postgres' && !config.database.connectionString?.trim()) {
    throw new Error(`Config at ${path} needs a non-empty database.connectionString.`);
  }
}

Type guard

function hasConnectionString(c: unknown): c is {database: {connectionString: string}} {
  return typeof c === 'object' && c !== null &&
    typeof (c as any).database?.connectionString === 'string' &&
    (c as any).database.connectionString.trim() !== '';
}

Prevention

When it happens

Trigger: Config file parses successfully, `config.database.mode` is not `embedded-postgres`, but `config.database.connectionString` is missing, empty, or whitespace-only. Produced at routines.ts:216.

Common situations: Configuring for external postgres but forgetting the connectionString field; setting an env var placeholder that resolves empty; partial config from a template that left the field blank.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/377b3cec3ac19d5c. Report an issue: GitHub.