a-b-street/abstreet · error · anyhow::Error
Unknown command
Error message
Unknown command
What it means
The catch-all arm of handle_command's match on the request path returns Err(anyhow!("Unknown command")) for any path that is not one of the recognized headless API routes. It signals the client called an endpoint this server does not implement.
Solutions
- Check the exact endpoint names in handle_command's match arms and correct the request path
- Verify client and server are from the same version of the codebase
- Note the error response body's context for the path and adjust the caller
Example fix
// before GET /sim/fast-forward // after GET /sim/ffwd
Defensive patterns
Strategy: validation
Validate before calling
// check the path against known endpoints before calling
const KNOWN = ['/sim/reset', '/sim/ffwd', '/geo/roads', ...];
if (!KNOWN.includes(path)) console.warn('unknown endpoint', path); Try / catch
let resp = client.get(path).await?;
if resp.text().await?.contains("Unknown command") {
// wrong endpoint; refresh client API against server version
} Prevention
- Generate the client from the server's match arms or keep them adjacent in code
- Pin client and server to the same build/version
- Watch for trailing-slash and case differences in paths
When it happens
Trigger: HTTP request to a path not in handle_command's match list (e.g. /sim/ffwd typo'd as /sim/fastforward, wrong trailing slash, or an endpoint added on the client but not the server).
Common situations: API contract drift between client and headless server version; typos in endpoint paths; hitting the server with a probe/health-check path it doesn't know.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- HTTP error
- missing GET parameter
- Giving up looking for a driving lane near
- Car with one-step route
- Two consecutive stops are on the same road, but they travel…
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/31ce8fd7c1208a83.
Report an issue: GitHub.
Appendix: source
Thrown at headless/src/main.rs:418
}
"/map/get-intersection-geometry" => {
let i = IntersectionID(get("id")?.parse::<usize>()?);
Ok(abstutil::to_json(&export_geometry(map, i)))
}
"/map/get-all-geometry" => Ok(abstutil::to_json(&map.export_geometry())),
"/map/get-nearest-road" => {
let pt = LonLat::new(get("lon")?.parse::<f64>()?, get("lat")?.parse::<f64>()?);
let mut closest = FindClosest::new();
for r in map.all_roads() {
closest.add(r.id, r.center_pts.points());
}
let threshold = Distance::meters(get("threshold_meters")?.parse::<f64>()?);
match closest.closest_pt(pt.to_pt(map.get_gps_bounds()), threshold) {
Some((r, _)) => Ok(r.0.to_string()),
None => bail!("No road within {} of {}", threshold, pt),
}
}
_ => Err(anyhow!("Unknown command")),
}
}
// TODO I think specifying the API with protobufs or similar will be a better idea.
#[derive(Serialize)]
struct FinishedTrip {
id: TripID,
person: PersonID,
duration: Option<Duration>,
distance_crossed: Distance,
mode: TripMode,
}
#[derive(Serialize)]
struct Delays {
#[serde(serialize_with = "serialize_btreemap")]
per_direction: BTreeMap<MovementID, Vec<Duration>>,View on GitHub (pinned to 0964f29315)