at://nekomimi.pet/sh.tangled.repo.issue/3m5xmb7kfax22
Back to Collection
Record JSON
{
"$type": "sh.tangled.repo.issue",
"body": "com.atproto.sync.subscribeRepos defines cid on repoOp as nullable\n```json \n\"repoOp\": {\n \"type\": \"object\",\n \"nullable\": [\n \"cid\"\n ],\n```\nhowever in the generated rust code, its not an Option\n\ngenerated rust code (crates/jacquard-api/src/com_atproto/sync/subscribe_repos.rs line ~2082):\n```rust\n pub struct RepoOp\u003c'a\u003e {\n pub action: jacquard_common::CowStr\u003c'a\u003e,\n pub cid: jacquard_common::types::cid::CidLink\u003c'a\u003e, // here\n pub path: jacquard_common::CowStr\u003c'a\u003e,\n pub prev: Option\u003cjacquard_common::types::cid::CidLink\u003c'a\u003e\u003e,\n }\n```\nwhen a delete operation is processed, DAG-CBOR operations then fail to deserialize \n\nminimal repro:\n```toml\n[package]\nname = \"jacquard-bug-repro\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\njacquard-api = { git = \"https://tangled.org/@nonbinary.computer/jacquard\", features = [\"streaming\"] }\njacquard-common = { git = \"https://tangled.org/@nonbinary.computer/jacquard\", features = [\"websocket\"] }\ntokio = { version = \"1\", features = [\"full\"] }\nn0-future = \"0.3\"\nurl = \"2\"\n```\n```rust\nuse jacquard_api::com_atproto::sync::subscribe_repos::{SubscribeRepos, SubscribeReposMessage};\nuse jacquard_common::xrpc::{SubscriptionClient, TungsteniteSubscriptionClient};\nuse n0_future::StreamExt;\nuse url::Url;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n let pds_url = Url::parse(\"wss://bsky.network\")?;\n println!(\"Connecting to {}...\", pds_url);\n\n let client = TungsteniteSubscriptionClient::from_base_uri(pds_url);\n let params = SubscribeRepos::new().build();\n let stream = client.subscribe(\u0026params).await?;\n\n println!(\"Connected! Waiting for a delete operation...\\n\");\n\n let (_sink, mut messages) = stream.into_stream();\n\n while let Some(result) = messages.next().await {\n match result {\n Ok(SubscribeReposMessage::Commit(commit)) =\u003e {\n println!(\"Commit from {}: {} ops\", commit.repo, commit.ops.len());\n }\n Err(e) =\u003e {\n return Err(e.into());\n }\n _ =\u003e {}\n }\n }\n\n Ok(())\n}\n```\n\nit should crash within seconds after processing a delete record\n\nI had to manually RepoOp.cid to Option\u003cCidLink\u003c'a\u003e\u003e: in the generated code but i dont know how to fix the codegen thats way over my head",
"createdAt": "2025-11-19T06:19:00Z",
"repo": "at://did:plc:yfvwmnlztr4dwkb7hwz55r2g/sh.tangled.repo/3lzrya6fcwv22",
"title": "RepoOp.cid should be Option\u003cCidLink\u003e - causes deserialization failure on delete operations"
}