a-b-street/abstreet · error · anyhow::Error
missing GET parameter
Error message
missing GET parameter {} What it means
The headless HTTP server's handle_command uses a local closure get(key) that looks up a query-string parameter and returns anyhow!("missing GET parameter {}") when absent. Every API path validates its required query parameters through this closure, so this error signals a malformed request to the API.
Solutions
- Include all required query parameters for the endpoint (check the match arms in handle_command for names)
- Fix typos/case in parameter names
- Update the client to the current headless API contract
- Encode parameters properly (percent-encode values like GPS points)
Example fix
// before curl 'http://localhost:1234/geo/roads' // after curl 'http://localhost:1234/geo/roads?pt=47.6,-122.3&threshold_meters=50'
Defensive patterns
Strategy: validation
Validate before calling
// client-side check before sending
const required = ['pt', 'threshold_meters'];
for (const k of required) {
if (!(k in params)) throw new Error(`missing GET parameter ${k}`);
} Try / catch
let resp = fetch(url).await?;
if !resp.status().is_success() {
let body = resp.text().await?;
if body.contains("missing GET parameter") { /* fix params and retry */ }
} Prevention
- Keep a documented list of required query params per endpoint
- Encode parameter values (GPS points, strings) with percent-encoding
- Match client param names exactly (case-sensitive) to the server
When it happens
Trigger: Sending an HTTP request to /sim/*, /map/*, or other endpoints without a required query parameter, e.g. GET /geo/roads?... omitting pt=..., or misspelling a parameter name.
Common situations: Hand-crafted curl requests missing params; client code and server API out of sync; typos in parameter names (case-sensitive); URL-encoded params lost by an intermediary.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- HTTP error
- Unknown command
- CityName::new( , ) has a country code that isn't two letters
- Dropdown has default_value , but none of the choices match…
- Bad CityName
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/4e143d9dc616f446.
Report an issue: GitHub.
Appendix: source
Thrown at headless/src/main.rs:151
.body(Body::from(format!("Bad command {}: {}", path, err)))
.unwrap()
}
},
)
}
fn handle_command(
path: &str,
params: &HashMap<String, String>,
body: &[u8],
sim: &mut Sim,
map: &mut Map,
load: &mut LoadSim,
) -> Result<String> {
let get = |key: &str| {
params
.get(key)
.ok_or_else(|| anyhow!("missing GET parameter {}", key))
};
match path {
// Controlling the simulation
"/sim/reset" => {
let (new_map, new_sim) = load.setup(&mut Timer::new("reset sim"));
*map = new_map;
*sim = new_sim;
Ok("sim reloaded".to_string())
}
"/sim/load" => {
let args: LoadSim = abstutil::from_json(body)?;
load.scenario = args.scenario;
load.modifiers = args.modifiers;
load.edits = args.edits;
// Also resetView on GitHub (pinned to 0964f29315)