can1357/oh-my-pi · error · std::io::Error

invalid glob `{pattern}`: {error}

Error message

invalid glob `{pattern}`: {error}

What it means

Frames of type 'rpc_chunk' are a protocol v2 (streaming chunk) feature enabled during negotiation. Receiving one while _protocol_v2_enabled is False means the server began speaking v2 without the client having negotiated it, so the client raises RpcError rather than misparsing the stream.

Source

Thrown at crates/pi-ast/src/ops.rs:378

			.unwrap_or(&absolute_path)
			.to_string_lossy()
			.replace('\\', "/");
		if globset.is_match(&relative_path)
			|| patterns.iter().any(|pattern| pattern == &relative_path)
		{
			files.push(MatchedFile { absolute_path, relative_path });
		}
	}
	files.sort_unstable_by(|left, right| left.relative_path.cmp(&right.relative_path));
	Ok(files)
}

fn build_globset(patterns: &[String]) -> Result<GlobSet, std::io::Error> {
	let mut builder = GlobSetBuilder::new();
	for pattern in patterns {
		if has_glob_syntax(pattern) {
			let glob = Glob::new(pattern).map_err(|error| {
				std::io::Error::new(
					std::io::ErrorKind::InvalidInput,
					format!("invalid glob `{pattern}`: {error}"),
				)
			})?;
			builder.add(glob);
		}
	}
	builder.build().map_err(std::io::Error::other)
}

#[must_use]
pub fn has_glob_syntax(pattern: &str) -> bool {
	pattern.contains('*') || pattern.contains('?') || pattern.contains('[')
}

fn compile_rust_contextual_pattern(pattern: &str) -> Option<Pattern> {
	let language = SupportLang::Rust;
	let context = format!("fn __rwp_wrapper() {{ {pattern}; }}");

View on GitHub (pinned to 9690622007)

Solutions

  1. Upgrade the Python client (omp_rpc) so protocol v2 negotiation is supported, or enable v2 in client options if available.
  2. Downgrade/configure the server to speak protocol v1, matching the client.
  3. Verify the negotiation exchange completes before the server sends commands (initialize handshake order).
  4. Catch RpcError and log the first frames to confirm which side skipped negotiation.

Example fix

// before
client = RpcClient(cmd, protocol_v2=False)  # server speaks v2 chunks
// after
client = RpcClient(cmd, protocol_v2=True)  # or upgrade client so negotiation enables v2
Defensive patterns

Strategy: try-catch

Validate before calling

# check protocol support before connecting
if server_supports_v2 and not client_supports_v2:
    raise RuntimeError("upgrade omp_rpc client: server requires protocol v2 (rpc_chunk frames)")

Type guard

def protocol_negotiated(client: RpcClient) -> bool:
    return client._protocol_v2_enabled or not server_requires_v2

Try / catch

try:
    result = await client.request("prompt", payload)
except RpcError as exc:
    if "protocol negotiation" in str(exc):
        raise RuntimeError("client/server protocol version mismatch — align versions") from exc
    raise

Prevention

When it happens

Trigger: Server version newer than the client emits rpc_chunk frames despite no v2 handshake (or handshake response lost/ignored); forcing legacy mode client-side against a v2-only server; server bug skipping the initialize/negotiation exchange.

Common situations: Version skew after upgrading the server binary but not the Python client, or pinning protocol=v1 for compatibility while the server defaults to v2 streaming.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/4078fc0c035a1c9b. Report an issue: GitHub.