spring-projects/spring-ai · error · IllegalArgumentException

Invalid Neo4j node label: ''. Labels must start with a lette

Error message

Invalid Neo4j node label: ''. Labels must start with a letter or underscore and contain only letters, digits, or underscores.

What it means

Neo4jChatMemoryRepositoryConfig validates all configured node labels (session, message, metadata, media, toolCall, toolResponse) against a SAFE_LABEL regex: labels must start with a letter or underscore and contain only letters, digits, or underscores. An invalid label (here an empty string) throws IllegalArgumentException at construction time to prevent broken/unsafe Cypher label interpolation.

Source

Thrown at memory-repositories/spring-ai-model-chat-memory-repository-neo4j/src/main/java/org/springframework/ai/chat/memory/repository/neo4j/Neo4jChatMemoryRepositoryConfig.java:113

	private Neo4jChatMemoryRepositoryConfig(Builder builder) {
		Assert.state(builder.driver != null, "driver must not be null");
		this.driver = builder.driver;
		this.sessionLabel = builder.sessionLabel;
		this.mediaLabel = builder.mediaLabel;
		this.messageLabel = builder.messageLabel;
		this.toolCallLabel = builder.toolCallLabel;
		this.metadataLabel = builder.metadataLabel;
		this.toolResponseLabel = builder.toolResponseLabel;
		validateLabels();
		ensureIndexes();
	}

	private void validateLabels() {
		for (String label : new String[] { this.sessionLabel, this.messageLabel, this.metadataLabel, this.mediaLabel,
				this.toolCallLabel, this.toolResponseLabel }) {
			if (!SAFE_LABEL.matcher(label).matches()) {
				throw new IllegalArgumentException("Invalid Neo4j node label: '" + label
						+ "'. Labels must start with a letter or underscore and contain only letters, digits, or underscores.");
			}
		}
	}

	/**
	 * Ensures that indexes exist on conversationId for Session nodes and index for
	 * Message nodes. This improves query performance for lookups and ordering.
	 */
	private void ensureIndexes() {
		try (var session = this.driver.session()) {
			// Index for conversationId on Session nodes
			String sessionIndexCypher = String.format(
					"CREATE INDEX session_conversation_id_index IF NOT EXISTS FOR (n:%s) ON (n.conversationId)",
					this.sessionLabel);
			// Index for index on Message nodes
			String messageIndexCypher = String
				.format("CREATE INDEX message_index_index IF NOT EXISTS FOR (n:%s) ON (n.index)", this.messageLabel);

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Set every label to a valid identifier, e.g. sessionLabel("session"), messageLabel("message")
  2. Check application.yml/properties for empty label keys and give them values or remove the overrides
  3. If using env vars, provide a default: ${NEO4J_MESSAGE_LABEL:message}

Example fix

// before
Neo4jChatMemoryRepositoryConfig.builder().messageLabel("").build();
// after
Neo4jChatMemoryRepositoryConfig.builder().messageLabel("message").build();
Defensive patterns

Strategy: validation

Validate before calling

Pattern SAFE = Pattern.compile("^[A-Za-z_][A-Za-z0-9_]*$");
if (label == null || !SAFE.matcher(label).matches()) {
    throw new IllegalArgumentException("Label must match [A-Za-z_][A-Za-z0-9_]*");
}

Type guard

boolean isValidLabel(String l) { return l != null && l.matches("[A-Za-z_][A-Za-z0-9_]*"); }

Try / catch

try { config = Neo4jChatMemoryRepositoryConfig.builder().messageLabel(label).build(); }
catch (IllegalArgumentException e) { config = Neo4jChatMemoryRepositoryConfig.builder().build(); } // defaults

Prevention

When it happens

Trigger: Building Neo4jChatMemoryRepositoryConfig with a label set to "" (e.g. .sessionLabel("") or a blank property bound from application.yml/properties).

Common situations: Empty spring.ai.chat.memory.repository.neo4j.* label properties in application.yml; environment-variable-driven config where the variable is unset and defaults to empty string; labels with spaces or hyphens.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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