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
- Set every label to a valid identifier, e.g. sessionLabel("session"), messageLabel("message")
- Check application.yml/properties for empty label keys and give them values or remove the overrides
- 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
- Give explicit valid values for all label properties; never leave them blank
- Use env var defaults like ${NEO4J_MESSAGE_LABEL:message}
- Avoid spaces and hyphens in Neo4j labels
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
- %s messages are not supported
- Single parameter must be of type ElicitRequest:
- First parameter must be of type Double or double: {method.ge
- Second parameter must be of type String: {method.getName()}
- Third parameter must be of type String: {method.getName()} i
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/4b76489d9d59641e.
Report an issue: GitHub.