Skip to content

Language server jumps to line 1 when a diagnostic location does not resolve #787

Description

@jeremi

What happens

range_for_location in crates/registry-language-server/src/relay_v2/index.rs resolves a
compiler diagnostic location such as resources[0].sourceColumnClassifications.id by walking the
authored YAML one dot-separated segment at a time. The mapping lookup uses ?:

YamlValue::Mapping(entries) => {
    let entry = entries.iter().find(|entry| entry.key.value == name)?;

so a single unresolvable segment abandons the whole walk and returns None, discarding the range
of every ancestor that did resolve. range_at then applies .unwrap_or_else(zero_range), and
zero_range() is Position(0,0)-Position(0,0).

Why it matters

The editor silently jumps to line 1, column 1 of registry.yaml rather than to the diagnostic's
subject. There is no error, no log, and no visible difference from a diagnostic that legitimately
belongs at the top of the file, so a location bug in the compiler presents to the adopter as a
merely confusing jump. The failure mode hides the very defect that caused it.

The test suite already treats zero_range() as a "this is broken" sentinel elsewhere:
all_acceptance_projects_are_compiler_clean_and_index_their_core_edges asserts operation symbols
never carry it. No equivalent assertion covers the compiler-diagnostic path.

Suggested direction

Degrade to the nearest ancestor that resolved instead of to the document origin. The walk already
tracks the last successful range in a local range variable before discarding it, so the change is
small: on a failed segment lookup, return the ancestor range rather than None.

Worth pairing with an assertion that no compiler diagnostic surfaced through the language server
resolves to zero_range() unless its location is genuinely the document root, which would turn
future location bugs into test failures rather than confusing jumps.

Provenance

Found while reviewing #785. The compiler-side location defect that exposed it is fixed in that PR;
this is the language server's independent robustness gap and is not fixed there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:relayRegistry Relay ownership.rustRust implementation work.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions