apache/cassandra · error · IllegalArgumentException
Provided insert statement has no bind variables
Error message
Provided insert statement has no bind variables
What it means
For offline SSTable writing, every value must be bound at runtime via rawAddRow. prepareInsert() throws IllegalArgumentException when the parsed statement has no bind variables at all, because there would be nothing to bind per row and the writer cannot compute partition keys or clustings.
Solutions
- Replace literal values in the INSERT with '?' bind variables.
- Pass actual row values per record via rawAddRow(Object[]/List/Map) instead of baking them into the CQL string.
- Verify getBindVariables() is non-empty conceptually: one '?' per column in the INSERT.
- For one-off static rows, still parameterize and bind once.
Example fix
// before
builder.using("INSERT INTO ks.tbl (k, v) VALUES ('a', 1)");
// after
builder.using("INSERT INTO ks.tbl (k, v) VALUES (?, ?)");
writer.rawAddRow("a", 1); Defensive patterns
Strategy: validation
Validate before calling
String cql = insertStmt;
int placeholders = cql.length() - cql.replace("?", "").length();
if (placeholders == 0) throw new IllegalArgumentException("INSERT must contain ? bind variables"); Try / catch
try { writer = builder.build(); }
catch (IllegalArgumentException e) { throw new IllegalStateException("parameterize the insert statement: " + e.getMessage(), e); } Prevention
- Always write INSERTs with '?' placeholders and bind values via rawAddRow.
- Never inline literal values into the CQL string.
- Lint generated statements for '?' presence.
- Keep row data in code/data files, not in the statement.
When it happens
Trigger: Passing a fully literal INSERT (no '?' placeholders) such as INSERT INTO ks.tbl (k, v) VALUES ('a', 1) to using(...).
Common situations: Hard-coded sample data inserted as a literal string; template generation code that inlined values instead of parameters; misunderstanding that rawAddRow values map to bound variables.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Bind variables are not allowed in CREATE MATERIALIZED VIEW…
- Conditional statements are not supported
- Counter update statements are not supported
- Provided preparedModificationStatement statement has no…
- there were markers(?) in CQL but bound variables
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/61eb606a2ea26875.
Report an issue: GitHub.
Appendix: source
Thrown at tools/stress/src/org/apache/cassandra/io/sstable/StressCQLSSTableWriter.java:704
/**
* Prepares insert statement for writing data to SSTable
*
* @return prepared Insert statement and it's bound names
*/
private UpdateStatement prepareInsert()
{
ClientState state = ClientState.forInternalCalls();
CQLStatement cqlStatement = insertStatement.prepare(state);
UpdateStatement insert = (UpdateStatement) cqlStatement;
insert.validate(state);
if (insert.hasConditions())
throw new IllegalArgumentException("Conditional statements are not supported");
if (insert.isCounter())
throw new IllegalArgumentException("Counter update statements are not supported");
if (insert.getBindVariables().isEmpty())
throw new IllegalArgumentException("Provided insert statement has no bind variables");
return insert;
}
}
public static <T extends CQLStatement.Raw> T parseStatement(String query, Class<T> klass, String type)
{
try
{
CQLStatement.Raw stmt = CQLFragmentParser.parseAnyUnhandled(CqlParser::query, query);
if (!stmt.getClass().equals(klass))
throw new IllegalArgumentException("Invalid query, must be a " + type + " statement but was: " + stmt.getClass());
return klass.cast(stmt);
}
catch (RecognitionException | RequestValidationException e)
{View on GitHub (pinned to 88fd0f6a0e)