facebook/flow · error

Peeking current location when not available

Error message

Peeking current location when not available

What it means

loc_skip_lookahead (rust_port/crates/flow_parser/src/parser_env.rs:1211) synthesizes a zero-width loc hint at the end of the last consumed token by calling env.last_loc(), which returns None until the lexer has produced at least one result (last_lex_result is unset before the first token). The expect fires when the helper is consulted before any token has been consumed. It is an internal assertion: the parser is asking for a previous-token-end location when no previous token exists.

Source

Thrown at rust_port/crates/flow_parser/src/parser_env.rs:1225

/// Answer questions about what comes next
pub(crate) mod peek {
    use super::*;
    use crate::token::TokenKind;

    pub(crate) fn token<'a>(env: &'a mut ParserEnv) -> &'a TokenKind {
        &env.lookahead_0().token_kind
    }

    pub(crate) fn loc<'a>(env: &'a mut ParserEnv) -> &'a Loc {
        &env.lookahead_0().loc
    }

    /// loc_skip_lookahead is used to give a loc hint to optional tokens such as type annotations
    pub(crate) fn loc_skip_lookahead(env: &ParserEnv) -> Loc {
        let loc = env
            .last_loc()
            .expect("Peeking current location when not available");
        Loc {
            start: loc.end,
            ..loc.dupe()
        }
    }

    pub(crate) fn errors(env: &mut ParserEnv) -> Vec<(Loc, ParseError)> {
        let errors = env.lookahead_0().errors.as_errors();
        if errors.is_empty() {
            Vec::new()
        } else {
            errors.to_vec()
        }
    }

    pub(crate) fn comments(env: &mut ParserEnv) -> Vec<Comment<Loc>> {
        let consumed_comments_pos = env.consumed_comments_pos;
        let comments = &env.lookahead_0().comments;

View on GitHub (pinned to 5c86586199)

Solutions

  1. Reproduce with the smallest input (often an empty string or one token) to confirm the at-start-of-input condition
  2. Ensure the calling parse rule consumes or lookaheads at least one token before asking for a last_loc-derived hint
  3. Prefer the lookahead-based loc (ParserEnv::lookahead_0().loc) when any token is available
  4. If you maintain this code, fall back to a start-of-file Loc instead of expecting when last_loc() is None

Example fix

// before
let loc = env.last_loc().expect("Peeking current location when not available");

// after: fall back to a synthesized start-of-file loc
let loc = env.last_loc()
    .map(|l| Loc { start: l.end, ..l.dupe() })
    .unwrap_or_else(Loc::at_start); // empty loc at position 0
Defensive patterns

Strategy: type-guard

Validate before calling

// Before asking for a loc hint derived from the previous token, ensure one exists
if env.last_loc().is_none() {
    // parser is at position 0: use a start-of-file loc, do not call loc_skip_lookahead
    return start_loc_hint();
}

Type guard

fn has_last_loc(env: &ParserEnv) -> bool {
    env.last_loc().is_some()
}

Try / catch

let loc = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| loc_skip_lookahead(env)))
    .unwrap_or_else(|_| Loc::at_start()); // fall back to position 0

Prevention

When it happens

Trigger: Calling loc_skip_lookahead (directly or via a parse rule that requests a loc hint for an optional token such as a missing type annotation) while the parser is still at the very start of input: empty files, files whose first token is the construct being parsed, or an error-recovery path that resets state before the first token is lexed.

Common situations: Parsing empty or single-token files through entry points that eagerly compute loc hints; refactors that reordered lookahead/loc-hint calls in parse rules; unit tests with minimal snippets.

Related errors


AI-assisted analysis of facebook/flow@5c86586199 (2026-08-20). Data as JSON: /api/errors/5ebf241277033530. Report an issue: GitHub.