[v2 Bug] Unicode characters cause incorrect inferred YAML diagnostic columns
- Dominant language
- Rust
- Stars
- 13.8k
- Forks
- 2.6k
- Avg merge
- 21h 31m
- Merged PRs (30d)
- 56
Description
### Is this a new bug in dbt v2.x compared to the latest version of dbt 1.x?
- [x] I believe this is a new bug in dbt v2.x
- [x] I have searched the existing issues and could not find a duplicate
### Current Behavior
When dbt infers a YAML error location with `with_hacky_yml_location`, a multibyte UTF-8 character before the offending token shifts the reported column to the right.
For a file containing:
```yaml
é foo
```
looking up `foo` returns:
```text
(line 1, column 4, byte index 3)
```
The token actually begins at Unicode-character column 3. Diagnostics and editor integrations therefore point to the wrong column for YAML lines containing non-ASCII text before the token.
### Expected Behavior
The inferred location should be:
```text
(line 1, column 3, byte index 3)
```
This matches dbt's `CodeLocation` contract: columns count Unicode characters, while indexes count bytes.
### Steps To Reproduce
1. Check out current `main` at `e308781defb22d4ef7c68733985e3c741dc64038`.
2. Add this focused test inside `crates/dbt-error/src/utils.rs`:
```rust
#[test]
fn unicode_text_uses_character_columns() {
let path = std::env::temp_dir().join("dbt-error-unicode-location.yml");
std::fs::write(&path, "é foo\n").unwrap();
assert_eq!(
find_locations("foo", &path).unwrap(),
Some((1, 3, 3)),
);
}
```
3. Run:
```shell
cargo test -p dbt-error unicode_text_uses_character_columns
```
4. The assertion fails because the actual result is `Some((1, 4, 3))`.
This was also reproduced through the public `FsError::with_hacky_yml_location` path, not only by inspecting the helper.
### Relevant log output
```shell
actual=(1, 4, 3) expected=(1, 3, 3)
assertion `left == right` failed
left: (1, 4, 3)
right: (1, 3, 3)
```
The existing crate tests pass independently:
```shell
cargo test -p dbt-error --lib --offline
test result: ok. 3 passed; 0 failed
```
### Environment
- OS: macOS 26.5.2
- CPU: ARM64
- dbt distribution and version: dbt Core v2 source, `main` at `e308781defb22d4ef7c68733985e3c741dc64038` (workspace version `2.0.0-alpha.3`)
- Adapter: Not adapter-specific
### Which database adapter are you using?
Not adapter-specific.
### Is this a discrepancy vs. dbt 1.x?
- [ ] Yes — this works in dbt 1.x but not in dbt v2.x
The corresponding dbt 1.x behavior was not evaluated.
### Additional Context
This is my first issue in `dbt-core`. I reviewed the contributor expectations and the v2 bug template, and I am happy to adjust the reproduction or scope based on maintainer feedback.
The root cause appears to be that [`str::find`'s byte offset is used directly as the column](https://github.com/dbt-labs/dbt-core/blob/e308781defb22d4ef7c68733985e3c741dc64038/crates/dbt-error/src/utils.rs#L62-L64), while [`CodeLocation.col` is explicitly a Unicode-character position and `CodeLocation.index` is a byte position](https://github.com/dbt-labs/dbt-core/blob/e308781defb22d4ef7c68733985e3c741dc64038/crates/dbt-frontend-common/src/error/code_location.rs#L8-L13).
A minimal fix would count `remaining_line[..index].chars()` for the column while preserving `index` as the byte offset, with the focused regression test above. No new dependency is needed.
Related umbrella: #14420 tracks incorrect or missing diagnostic spans, but does not currently describe this byte-versus-character failure.
Contributor guide
Assessment
This issue has not been assessed yet.