a-b-street/abstreet · error · anyhow::Error

can't fulfill

Error message

can't fulfill {}

What it means

Map::pathfind_v2 delegates to the pathfinder and unwraps its Option<PathV2>; when the pathfinder cannot produce a path for the request, this error is thrown with the request printed. It is the standard 'no route exists for this PathRequest' failure, meaning no connected sequence of lanes respecting the request's constraints links start to goal.

Solutions

  1. Inspect the printed PathRequest and confirm start/goal are on connected lanes of the required type
  2. Retry without restrictive path constraints or with different RoutingParams
  3. Verify the map was rebuilt after edits so the pathfinder isn't stale (the assert guards this)
  4. Check graph connectivity between the endpoints before pathfinding, e.g. via should_use_transit or reachability probes

Example fix

// before
let path = map.pathfind(req).ok_or(anyhow!("no path"))?;
// after
let path = match map.pathfind(req.clone()) {
    Ok(p) => p,
    Err(e) => {
        warn!("no path for {:?}: {}", req, e);
        return None; // or fall back to a different mode
    }
};
Defensive patterns

Strategy: try-catch

Validate before calling

// probe connectivity before pathfinding
if map.should_use_transit(start, end).is_none() && req.end.lane().road == req.start.lane().road == false {
    // consider checking reachability via a cheaper pathfind on a subset
}

Try / catch

match map.pathfind(req.clone()) {
    Ok(p) => p,
    Err(e) if e.to_string().starts_with("can't fulfill") => {
        warn!("unroutable: {}", e);
        fallback_route_or_cancel()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling map.pathfind(req) (which calls pathfind_v2) where PathfinderWise::pathfind returns None: start/end positions on disconnected parts of the graph, wrong path constraints (e.g. requiring a lane type the route can't use), or a stale pathfinder (pathfinder_dirty asserted).

Common situations: Routing between a building and a destination with no driving/walking connectivity; bus-only trips where no transit route connects the stops; requests built against an old map after edits; filtering out roads (e.g. avoid highways) that removes all routes.

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


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/b8d06bd7add67266. Report an issue: GitHub.

Appendix: source

Thrown at map_model/src/map.rs:680

    }

    pub fn pathfind(&self, req: PathRequest) -> Result<Path> {
        self.pathfind_v2(req)?.into_v1(self)
    }
    pub fn pathfind_with_params(
        &self,
        req: PathRequest,
        params: &RoutingParams,
        cache_custom: PathfinderCaching,
    ) -> Result<Path> {
        self.pathfind_v2_with_params(req, params, cache_custom)?
            .into_v1(self)
    }
    pub fn pathfind_v2(&self, req: PathRequest) -> Result<PathV2> {
        assert!(!self.pathfinder_dirty);
        self.pathfinder
            .pathfind(req.clone(), self)
            .ok_or_else(|| anyhow!("can't fulfill {}", req))
    }
    pub fn pathfind_v2_with_params(
        &self,
        req: PathRequest,
        params: &RoutingParams,
        cache_custom: PathfinderCaching,
    ) -> Result<PathV2> {
        assert!(!self.pathfinder_dirty);
        self.pathfinder
            .pathfind_with_params(req.clone(), params, cache_custom, self)
            .ok_or_else(|| anyhow!("can't fulfill {}", req))
    }
    pub fn should_use_transit(
        &self,
        start: Position,
        end: Position,
    ) -> Option<(TransitStopID, Option<TransitStopID>, TransitRouteID)> {
        assert!(!self.pathfinder_dirty);

View on GitHub (pinned to 0964f29315)