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"
}