spring-projects/spring-ai · error · IllegalArgumentException

DataSource must be set (either via dataSource() or jdbcTempl

Error message

DataSource must be set (either via dataSource() or jdbcTemplate())

What it means

JdbcChatMemoryRepository.Builder.build() resolves the JdbcTemplate used by the repository. If neither jdbcTemplate() nor dataSource() was supplied on the builder, resolveJdbcTemplate() throws IllegalArgumentException. The repository cannot execute any SQL without one of these.

Source

Thrown at memory-repositories/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepository.java:238

			this.platformTransactionManager = txManager;
			return this;
		}

		public JdbcChatMemoryRepository build() {
			DataSource effectiveDataSource = resolveDataSource();
			JdbcChatMemoryRepositoryDialect effectiveDialect = resolveDialect(effectiveDataSource);
			return new JdbcChatMemoryRepository(resolveJdbcTemplate(), effectiveDialect,
					this.platformTransactionManager);
		}

		private JdbcTemplate resolveJdbcTemplate() {
			if (this.jdbcTemplate != null) {
				return this.jdbcTemplate;
			}
			if (this.dataSource != null) {
				return new JdbcTemplate(this.dataSource);
			}
			throw new IllegalArgumentException("DataSource must be set (either via dataSource() or jdbcTemplate())");
		}

		private DataSource resolveDataSource() {
			if (this.dataSource != null) {
				return this.dataSource;
			}
			if (this.jdbcTemplate != null && this.jdbcTemplate.getDataSource() != null) {
				return this.jdbcTemplate.getDataSource();
			}
			throw new IllegalArgumentException("DataSource must be set (either via dataSource() or jdbcTemplate())");
		}

		private JdbcChatMemoryRepositoryDialect resolveDialect(DataSource dataSource) {
			if (this.dialect == null) {
				return JdbcChatMemoryRepositoryDialect.from(dataSource);
			}
			else {
				warnIfDialectMismatch(dataSource, this.dialect);

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Call .dataSource(...) on the builder with your DataSource bean
  2. Or call .jdbcTemplate(...) with an existing JdbcTemplate bean
  3. If using Spring Boot, verify a DataSource bean exists and is injectable (starter-jdbc or starter-data-jpa on classpath)
  4. Check auto-configuration ordering so the repository bean is created after the DataSource

Example fix

// before
JdbcChatMemoryRepository repo = JdbcChatMemoryRepository.builder().build();
// after
JdbcChatMemoryRepository repo = JdbcChatMemoryRepository.builder()
    .dataSource(dataSource)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (dataSource == null && jdbcTemplate == null) {
    throw new IllegalStateException("Configure dataSource() or jdbcTemplate() before build()");
}

Try / catch

try { repo = JdbcChatMemoryRepository.builder().build(); }
catch (IllegalArgumentException e) { repo = JdbcChatMemoryRepository.builder().dataSource(defaultDs).build(); }

Prevention

When it happens

Trigger: Calling JdbcChatMemoryRepository.builder().build() (or via JdbcChatMemoryConfig) without calling either .dataSource(ds) or .jdbcTemplate(jt) first.

Common situations: Forgot to wire the DataSource bean into the builder; copied a config example and removed the dataSource() line; building the repository manually in tests instead of via Spring auto-configuration.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/341b584e493cb338. Report an issue: GitHub.