t8y2/dbx · error
checked length
Error message
checked length
What it means
join_condition_clauses in the DynamoDB query builder collapses a list of ConditionClauses with an AND/OR operator. When exactly one clause is present it short-circuits with clauses.into_iter().next().expect("checked length"); the expect is protected by the len()==1 check directly above and panics only if that guard is removed or reordered.
Source
Thrown at crates/dbx-core/src/db/dynamodb_driver.rs:287
.and_then(|object| object.get("$regex"))
.and_then(Value::as_str)
.ok_or_else(|| format!("Unsupported DynamoDB $not condition for {field}"))?;
format!("NOT contains({path}, {})", self.value(&Value::String(nested.to_string()))?)
}
other => return Err(format!("Unsupported DynamoDB filter operator: {other}")),
};
clauses.push(clause);
}
if clauses.is_empty() {
return Err(format!("DynamoDB filter for {field} does not contain a condition"));
}
Ok(clauses.join(" AND "))
}
}
fn join_condition_clauses(clauses: Vec<ConditionClause>, operator: &str, precedence: u8) -> ConditionClause {
if clauses.len() == 1 {
return clauses.into_iter().next().expect("checked length");
}
let expression = clauses
.into_iter()
.map(
|clause| {
if clause.precedence < precedence {
format!("({})", clause.expression)
} else {
clause.expression
}
},
)
.collect::<Vec<_>>()
.join(operator);
ConditionClause { expression, precedence }
}
pub fn endpoint_url(config: &ConnectionConfig, host: &str, port: u16) -> String {View on GitHub (pinned to c0390bff16)
Solutions
- Keep the len()==1 guard immediately before extraction; prefer `let Some(clause) = clauses.into_iter().next() else { ... }`.
- Handle the empty-vec case explicitly (return a trivially-true clause or error) so the join never sees unexpected lengths.
- Add a unit test joining 0, 1, and 2+ clauses to lock the behavior.
- If panics are unacceptable in the query builder, switch join_condition_clauses to return Result<ConditionClause, String>.
Example fix
// before
if clauses.len() == 1 {
return clauses.into_iter().next().expect("checked length");
}
// after
if let Some(single) = clauses.into_iter().next() {
if matches!(clauses_len_hint, 1) { return single; }
}
// or simpler:
if clauses.len() == 1 {
return match clauses.into_iter().next() { Some(c) => c, None => return trivially_true_clause() };
} Defensive patterns
Strategy: type-guard
Validate before calling
// before joining condition clauses, handle degenerate lengths
if clauses.is_empty() { return Ok(default_clause()); } // skip join entirely Type guard
fn single_clause(clauses: Vec<ConditionClause>) -> Option<ConditionClause> {
if clauses.len() == 1 { clauses.into_iter().next() } else { None }
} Try / catch
if clauses.len() == 1 {
return match clauses.into_iter().next() {
Some(c) => c,
None => return default_clause(),
};
} Prevention
- Handle 0-, 1-, and N-clause cases explicitly in the query builder.
- Add unit tests covering each clause-count branch.
- Use let-else or match instead of expect guarded by separate length checks.
- Keep guard and extraction in the same expression scope so refactors cannot separate them.
When it happens
Trigger: Unreachable while `if clauses.len() == 1` precedes the into_iter().next(); a panic would indicate a refactor dropped the guard. Users never see this panic — with zero clauses callers skip joining, and with multiple clauses the code falls through to parenthesized combination.
Common situations: Builders constructing DynamoDB filter expressions from key conditions, filter expressions, or user query predicates; library maintainers refactoring condition_clause/join_condition_clauses; automated tests feeding single-condition queries (e.g. one equality key condition).
Related errors
- checked above
- a batch cancellation token is always available
- driver token registered
- a cancellation token is always available
- checked one driver
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/db0bdfc65943c05f.
Report an issue: GitHub.