rust-lang/rust-analyzer · error
Could not find file position in fixture. Did you forget to a
Error message
Could not find file position in fixture. Did you forget to add an `$0`?
What it means
This panic comes from the test-fixture helper that parses a fixture string and extracts the cursor position. rust-analyzer test fixtures mark positions with `$0`; if the fixture text contains no `$0` marker, file_position is None and the expect panics. It means the test author forgot to mark where the cursor/selection should be.
Source
Thrown at crates/test-fixture/src/lib.rs:223
#[track_caller]
fn with_range(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FileRange) {
let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture);
let range = range_or_offset.expect_range();
(db, FileRange { file_id, range })
}
/// See the trait documentation for more information on fixtures.
#[track_caller]
fn with_range_or_offset(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
) -> (Self, EditionedFileId, RangeOrOffset) {
let mut db = Self::default();
let fixture = ChangeFixture::parse(ra_fixture);
fixture.change.apply(&mut db);
let (file_id, range_or_offset) = fixture
.file_position
.expect("Could not find file position in fixture. Did you forget to add an `$0`?");
let file_id = EditionedFileId::from_span_file_id(&db, file_id);
(db, file_id, range_or_offset)
}
fn test_crate(&self) -> Crate {
all_crates(self).iter().copied().find(|&krate| !krate.data(self).origin.is_lang()).unwrap()
}
}
impl<DB: SourceDatabase + Default + 'static> WithFixture for DB {}
pub struct ChangeFixture {
pub file_position: Option<(span::EditionedFileId, RangeOrOffset)>,
pub file_lines: Vec<usize>,
pub files: Vec<span::EditionedFileId>,
pub change: ChangeWithProcMacros,
pub sysroot_files: Vec<FileId>,
}View on GitHub (pinned to e8f7e90aa3)
Solutions
- Add `$0` inside the fixture text at the position of interest, e.g. `fn f() { foo$0(); }`.
- If using comment-based markers (`//^`), keep `$0` only if the API needs a cursor too; otherwise use the marker-based helper instead.
- Ensure `$0` appears exactly once if the helper expects a single file position.
- Check the fixture annotation syntax in docs/book/src/contributing/testing.md if unsure which marker your helper requires.
Example fix
// before
let (db, file_id, range) = TestDb::with_range_or_offset(r#"fn main() { foo(); }"#);
// after
let (db, file_id, range) = TestDb::with_range_or_offset(r#"fn main() { foo$0(); }"#); Defensive patterns
Strategy: validation
Validate before calling
fn assert_fixture_has_cursor(fixture: &str) {
assert!(fixture.contains("$0"), "fixture must contain $0 cursor marker");
} Try / catch
// Called from #[should_panic] tests only; otherwise validate before calling:
assert!(ra_fixture.contains("$0"));
let (db, file_id, pos) = TestDb::with_range_or_offset(ra_fixture); Prevention
- Always include exactly one $0 in position-sensitive fixtures.
- Use comment markers (//^) only when using marker-based helpers that don't need $0.
- Re-read docs/book/src/contributing/testing.md when adopting a new test helper.
When it happens
Trigger: Calling TestDb::with_range_or_offset (or helpers like with_single_file_with_position that go through it) with a ra_fixture string lacking `$0`, or where `$0` was consumed by another marker such as `//^` annotations without an actual `$0`.
Common situations: Writing a new expect/infer test and forgetting the cursor marker; copying a fixture that used `//^^^` comment annotations only; `$0` accidentally removed during fixture cleanup (testing conventions require minimal fixtures).
Related errors
- missing default crate root, specify a main.rs or lib.rs
- We explicitly do not provide canonicalization API, as that i
- bad kind {other}
- bad spacing {other}
- bad tag: {other}
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/4cd66b564caeb218.
Report an issue: GitHub.