lbjlaq/Antigravity-Manager · error

JSONC normalization preserves UTF-8

Error message

JSONC normalization preserves UTF-8

What it means

strip_jsonc_comments removes // and /* */ comments from JSONC while preserving string literals, then converts the byte buffer back to String. The expect asserts the remaining bytes are valid UTF-8; this can only fail if the slicing logic corrupted a multi-byte character boundary.

Solutions

  1. Ensure the config file is valid UTF-8 (re-save with UTF-8 encoding)
  2. If it reproduces on valid UTF-8 input, fix the byte-index arithmetic in strip_jsonc_comments so multi-byte chars inside strings are pushed verbatim
  3. Use String::from_utf8_lossy as a defensive fallback while debugging

Example fix

// before
String::from_utf8(out).expect("JSONC normalization preserves UTF-8")
// after
String::from_utf8(out).unwrap_or_else(|e| String::from_utf8_lossy(e.as_bytes()).into_owned())
Defensive patterns

Strategy: validation

Validate before calling

if let Err(bad) = std::str::from_utf8(&input_bytes) { return Err(format!("config not UTF-8 at byte {}", bad.valid_up_to())); }

Try / catch

String::from_utf8(out).map_err(|e| anyhow::anyhow!("jsonc output not UTF-8: {}", e))?

Prevention

When it happens

Trigger: Parsing an OpenCode config whose bytes are not valid UTF-8 after comment stripping — realistically a bug in index arithmetic cutting into a multi-byte UTF-8 sequence, or input read as lossy/invalid bytes.

Common situations: Config file saved with an encoding that produces invalid UTF-8 (e.g. partially decoded bytes); a regression in the stripper's byte offsets when scanning string contents.

Related errors


AI-assisted analysis of lbjlaq/Antigravity-Manager@90a2b6b207 (2026-09-19). Data as JSON: /api/errors/5b62ff6a77547ab4. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/proxy/opencode_sync.rs:401

                }
            }
            b'/' if i + 1 < bytes.len() && bytes[i + 1] == b'*' => {
                // Block comment: skip until closing */.
                i += 2;
                while i + 1 < bytes.len() && !(bytes[i] == b'*' && bytes[i + 1] == b'/') {
                    i += 1;
                }
                i = (i + 2).min(bytes.len());
            }
            _ => {
                out.push(c);
                i += 1;
            }
        }
    }

    // Only ASCII syntax is removed; all UTF-8 string bytes remain intact.
    String::from_utf8(out).expect("JSONC normalization preserves UTF-8")
}

/// Remove trailing commas (a `,` followed, after optional whitespace, by a closing
/// `}` or `]`) so `serde_json` can parse JSONC that permits them. Like the comment
/// stripper, this respects string literals so a comma at the end of a string value is
/// never touched.
fn strip_jsonc_trailing_commas(input: &str) -> String {
    let bytes = input.as_bytes();
    let mut out = Vec::with_capacity(input.len());
    let mut i = 0;
    let mut in_string = false;

    while i < bytes.len() {
        let c = bytes[i];

        if in_string {
            out.push(c);
            if c == b'\\' && i + 1 < bytes.len() {

View on GitHub (pinned to 90a2b6b207)