apache/cassandra · error · SyntaxException
Invalid value for property
Error message
Invalid value for property '%s'. It should be a map.
What it means
PropertyDefinitions.getMap() extracts a CQL property value (e.g. from CREATE/ALTER TABLE WITH options or credentials) that must be a map of string options. When the parsed property value exists but is neither a Map nor an empty Set (the sentinel for '{}'), the parser cannot interpret it as an option map and throws a SyntaxException. It signals that the syntax used for the property's value does not match the expected map literal form.
Solutions
- Wrap the property value in map-literal braces: WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3}
- Quote each key and string value inside the map with single quotes
- Check which property is named in the error and verify its expected shape in the CQL docs
- If building CQL from code, ensure map-typed properties are rendered as {'k':'v', ...}
Example fix
// before
CREATE KEYSPACE ks WITH replication = SimpleStrategy;
// after
CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}; Defensive patterns
Strategy: validation
Validate before calling
if (!/\{\s*'[^']+'\s*:\s*'[^']+'/.test(propValue) && !/^\{\s*\}$/.test(propValue)) throw new Error(`Property ${name} must be a map literal: {'k':'v'}`); Type guard
function isMapLiteral(v) { return typeof v === 'string' ? v.trim().startsWith('{') && v.trim().endsWith('}') : v instanceof Map; } Prevention
- Always render map-typed CQL properties as {'key':'value'} literals
- Keep a helper that serializes option objects to CQL map syntax
- Validate generated CQL with a parser (or run against a test keyspace) before deployment
When it happens
Trigger: Executing CQL like CREATE TABLE ... WITH options = 'string' or ALTER KEYSPACE WITH replication = 'SimpleStrategy' where the value after '=' parses to a scalar/list instead of a map literal, e.g. replication = SimpleStrategy or options = [1,2].
Common situations: Copy-pasted CQL missing the braces around map values (replication = SimpleStrategy instead of {'class': 'SimpleStrategy'}); quoting mistakes that make the parser treat the value as a string; hand-written migration scripts or tooling generating CQL programmatically.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- (dynamic first syntax error message from parser/lexer)
- Failed parsing : [ ] reason
- Failed parsing statement
- FrozenType() only accepts one parameter
- Invalid boolean value
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/481f896c0adea674.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java:114
if (val == null)
return null;
if (val instanceof Map && ((Map<?, ?>)val).isEmpty()) // to solve the ambiguity between empty map and empty set
return Collections.emptySet();
if (!(val instanceof Set))
throw new SyntaxException(String.format("Invalid value for property '%s'. It should be a set of identifiers.", name));
return (Set<QualifiedName>) val;
}
@Nullable
protected Map<String, String> getMap(String name) throws SyntaxException
{
Object val = properties.get(name);
if (val == null)
return null;
if (val instanceof Set && ((Set<?>)val).isEmpty()) // to solve the ambiguity between empty map and empty set
return Collections.emptyMap();
if (!(val instanceof Map))
throw new SyntaxException(format("Invalid value for property '%s'. It should be a map.", name));
return (Map<String, String>)val;
}
public boolean getBoolean(String key, boolean defaultValue) throws SyntaxException
{
String value = getString(key);
return value != null ? parseBoolean(key, value) : defaultValue;
}
public static boolean parseBoolean(String key, String value) throws SyntaxException
{
if (null == value)
throw new IllegalArgumentException("value argument can't be null");
String lowerCasedValue = toLowerCaseLocalized(value);
if (POSITIVE_PATTERN.matcher(lowerCasedValue).matches())
return true;View on GitHub (pinned to 88fd0f6a0e)