spring-projects/spring-framework · error · IllegalStateException

No StringValueResolver specified - pass a resolver object in

Error message

No StringValueResolver specified - pass a resolver object into the constructor or override the 'resolveStringValue' method

What it means

BeanDefinitionVisitor.resolveStringValue delegates placeholder resolution to a StringValueResolver supplied at construction. If no resolver was provided (the field is null) and the subclass did not override resolveStringValue, visiting a bean definition that contains String values (placeholders like ${...}) fails immediately with this IllegalStateException.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java:288

			Object val = entry.getValue();
			Object newVal = resolveValue(val);
			newContent.put(newKey, newVal);
			entriesModified = entriesModified || (newVal != val || newKey != key || newKeyHash != keyHash);
		}
		if (entriesModified) {
			mapVal.clear();
			mapVal.putAll(newContent);
		}
	}

	/**
	 * Resolve the given String value, for example parsing placeholders.
	 * @param strVal the original String value
	 * @return the resolved String value
	 */
	protected @Nullable String resolveStringValue(String strVal) {
		if (this.valueResolver == null) {
			throw new IllegalStateException("No StringValueResolver specified - pass a resolver " +
					"object into the constructor or override the 'resolveStringValue' method");
		}
		String resolvedValue = this.valueResolver.resolveStringValue(strVal);
		// Return original String if not modified.
		return (strVal.equals(resolvedValue) ? strVal : resolvedValue);
	}

}

View on GitHub (pinned to e8729d0438)

Solutions

  1. Pass a StringValueResolver (e.g. from environment::resolveRequiredPlaceholders) into the BeanDefinitionVisitor constructor.
  2. Override resolveStringValue in your subclass to implement resolution directly.
  3. Prefer PropertySourcesPlaceholderConfigurer / ConfigurableEnvironment.resolvePlaceholders for normal placeholder resolution instead of using the visitor directly.

Example fix

// before
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(null);
visitor.visitBeanDefinition(beanDef);
// after
StringValueResolver r = str -> env.resolveRequiredPlaceholders(str);
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(r);
visitor.visitBeanDefinition(beanDef);
Defensive patterns

Strategy: validation

Validate before calling

if (visitorResolver == null && placeholderPresent(beanDefinition)) {
  throw new IllegalStateException("BeanDefinitionVisitor needs a StringValueResolver to resolve placeholders");
}

Type guard

boolean resolverAvailable(@Nullable StringValueResolver r) {
  return r != null;
}

Prevention

When it happens

Trigger: Constructing a BeanDefinitionVisitor without a StringValueResolver and then visiting values that need resolving; or a subclass that calls super.resolveStringValue without supplying a resolver.

Common situations: Programmatic use of BeanDefinitionVisitor (e.g. PropertyPlaceholderConfigurer-like processing) without passing PropertyResolver.strValResolver; misusing the visitor standalone instead of through PropertySourcesPlaceholderConfigurer; custom visitor subclass forgetting to inject a resolver.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/d488ba36a53a9a7f.json. Report an issue: GitHub.