{"record":{"id":"c7042578a31d4221","repo":"spacedriveapp/spacedrive","slug":"isquery-query-action-failed-json-str","errorCode":null,"errorMessage":"${isQuery ? \"Query\" : \"Action\"} failed: ${JSON.stringify(error)}","messagePattern":"(.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ts-client/src/client.ts","lineNumber":219,"sourceCode":"\t\t\t: {\n\t\t\t\t\tAction: {\n\t\t\t\t\t\tmethod: wireMethod,\n\t\t\t\t\t\tlibrary_id: this.currentLibraryId, // ← Sibling field!\n\t\t\t\t\t\tpayload: input,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\tconst response = await this.transport.sendRequest(request);\n\n\t\t// Handle different response formats\n\t\tif (\"JsonOk\" in response) {\n\t\t\treturn response.JsonOk;\n\t\t} else if (\"json\" in response) {\n\t\t\t// Wire protocol uses lowercase \"json\" for success\n\t\t\treturn response.json;\n\t\t} else if (\"Error\" in response || \"error\" in response) {\n\t\t\tconst error = response.Error || response.error;\n\t\t\tthrow new Error(\n\t\t\t\t`${isQuery ? \"Query\" : \"Action\"} failed: ${JSON.stringify(error)}`,\n\t\t\t);\n\t\t} else {\n\t\t\tthrow new Error(`Unexpected response: ${JSON.stringify(response)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Subscribe to events from the daemon\n\t */\n\tasync subscribe(callback?: (event: Event) => void): Promise<() => void> {\n\t\tconst unlisten = await this.transport.subscribe((event) => {\n\t\t\tif (callback) {\n\t\t\t\tcallback(event);\n\t\t\t}\n\t\t});\n\n\t\treturn unlisten;","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/packages/ts-client/src/client.ts#L201-L237","documentation":"Returned by create_conduit when a sync_conduit row with the same (source_entry_id, target_entry_id) pair already exists. The duplicate check queries sync_conduit filtered on both columns before inserting, so re-submitting an identical pair is rejected rather than creating a second conduit.","triggerScenarios":"Calling create_conduit twice with the same source/target entry IDs — double-click on a create button, a client retry after a timeout where the first request actually succeeded, or re-adding a previously created pair.","commonSituations":"Duplicate form submission without idempotency key; the UI not refreshing its conduit list after creation; retry logic that re-sends a completed request.","solutions":["List existing conduits (list_all) and reuse the existing one instead of creating a new one.","If you truly want a fresh conduit, delete the existing one with delete_conduit first, then create.","Disable the submit action while the request is in flight to prevent double-submission."],"exampleFix":"// before\nlet c = svc.create_conduit(src, tgt, mode, sched.clone()).await?;\n\n// after (idempotent create)\nlet c = match svc.create_conduit(src, tgt, mode.clone(), sched.clone()).await {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"already exists\") => {\n        svc.list_all().await?.into_iter()\n            .find(|c| c.source_entry_id == src && c.target_entry_id == tgt)\n            .ok_or(e)?\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"validation","validationCode":"// Idempotent create: check for an existing pair first.\nasync fn find_existing(\n    svc: &ConduitService,\n    src: i32,\n    tgt: i32,\n) -> Result<Option<sync_conduit::Model>> {\n    Ok(svc.list_all()\n        .await?\n        .into_iter()\n        .find(|c| c.source_entry_id == src && c.target_entry_id == tgt))\n}","typeGuard":null,"tryCatchPattern":"match svc.create_conduit(src, tgt, mode, sched).await {\n    Ok(c) => Ok(c),\n    Err(e) if e.to_string().contains(\"already exists\") => {\n        find_existing(svc, src, tgt).await?.ok_or(e) // reuse, don't duplicate\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Debounce/disable the create button while a request is in flight.","Refresh the conduit list after creation so retries see the new row.","Treat create as idempotent on the (source, target) pair in client logic."],"tags":["rust","file-sync","duplicate","idempotency"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}