{"record":{"id":"211f2cbfdf21ecf5","repo":"spacedriveapp/spacedrive","slug":"failed-to-read-service-account-file","errorCode":null,"errorMessage":"Failed to read service account file: {}","messagePattern":"Failed to read service account file: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/domains/cloud/setup.rs","lineNumber":315,"sourceCode":"\t\t},\n\t};\n\n\texecute_add_cloud(ctx, input).await\n}\n\nasync fn add_gcs_interactive(ctx: &Context) -> Result<()> {\n\tlet name = text(\"Volume name (e.g., 'My GCS Bucket')\", false)?.unwrap();\n\tlet bucket = text(\"Bucket name\", false)?.unwrap();\n\tlet root = text(\"Root path (leave empty for entire bucket)\", true)?;\n\tlet endpoint = text(\"Custom endpoint (leave empty for default)\", true)?;\n\n\tprintln!(\"\\nService Account Setup:\");\n\tprintln!(\"  You'll need a service account JSON key from Google Cloud Console\");\n\tprintln!(\"  Visit: https://console.cloud.google.com/iam-admin/serviceaccounts\\n\");\n\n\tlet service_account_path = text(\"Path to service account JSON file\", false)?.unwrap();\n\tlet credential = std::fs::read_to_string(&service_account_path)\n\t\t.map_err(|e| anyhow::anyhow!(\"Failed to read service account file: {}\", e))?;\n\n\tprintln!(\"\\nSummary:\");\n\tprintln!(\"  Provider: Google Cloud Storage\");\n\tprintln!(\"  Name:     {}\", name);\n\tprintln!(\"  Bucket:   {}\", bucket);\n\tif let Some(ref r) = root {\n\t\tprintln!(\"  Root:     {}\", r);\n\t}\n\tif let Some(ref e) = endpoint {\n\t\tprintln!(\"  Endpoint: {}\", e);\n\t}\n\tprintln!();\n\n\tconfirm_or_abort(\"Add this cloud volume?\", false)?;\n\n\tlet input = VolumeAddCloudInput {\n\t\tservice: CloudServiceType::GoogleCloudStorage,\n\t\tdisplay_name: name.clone(),","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/domains/cloud/setup.rs#L297-L333","documentation":"Returned by SyncResolver::calculate_operations when SyncMode::from_str(&conduit.sync_mode) fails on the conduit's stored mode string. This is the same parse that sync_now performs later (mod.rs:93); the resolver hits it first while choosing a strategy (Mirror/Bidirectional/Selective in the match below). An unrecognized string aborts operation calculation.","triggerScenarios":"calculate_operations runs on a conduit whose sync_mode column holds a string outside the accepted variants — version drift in enum variant names, manual DB edits, or a client that submitted free text that was stored verbatim via create_conduit's sync_mode handling.","commonSituations":"Upgrading between versions where SyncMode variants were renamed; seed/import scripts writing arbitrary strings; copy-paste typos in manual updates.","solutions":["Read the stored value: SELECT sync_mode FROM sync_conduit WHERE id = <id> and compare with the strings SyncMode::from_str accepts (see the sync_conduit entity).","Update the row to a valid mode string ('mirror' | 'bidirectional' | 'selective').","Make create_conduit's mode input a typed enum end-to-end so only valid strings can be persisted."],"exampleFix":"-- before\nSELECT sync_mode FROM sync_conduit; -- 'two-way'\n\n-- after\nUPDATE sync_conduit SET sync_mode = 'bidirectional' WHERE sync_mode = 'two-way';","handlingStrategy":"validation","validationCode":"fn sync_mode_is_valid(s: &str) -> bool {\n    sync_conduit::SyncMode::from_str(s).is_some()\n}\n\n// before calculate_operations:\nif !sync_mode_is_valid(&conduit.sync_mode) {\n    return Err(anyhow::anyhow!(\"conduit {} has corrupt sync_mode '{}'\", conduit.id, conduit.sync_mode));\n}","typeGuard":null,"tryCatchPattern":"match resolver.calculate_operations(&conduit).await {\n    Ok(ops) => Ok(ops),\n    Err(e) if e.to_string() == \"Invalid sync mode\" => {\n        // fail fast with the offending value for a targeted DB fix\n        Err(anyhow::anyhow!(\"fix sync_mode='{}' on conduit {}\", conduit.sync_mode, conduit.id))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Use enum-typed inputs end-to-end so only valid mode strings reach the DB.","Include the offending string and conduit id in error context when wrapping.","Audit sync_mode values as part of upgrade/migration checklists."],"tags":["rust","file-sync","enum-parsing","data-integrity"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}