Kuberwastaken/claurst · error

Settings sync upload: unexpected status

Error message

Settings sync upload: unexpected status {}

What it means

The settings-sync PUT that uploads changed entries returned a non-success status — the formatted code is what the server answered with (e.g. 401 expired token, 409 conflict, 5xx). The batch of entries was not persisted server-side.

Solutions

  1. Retry the upload; entries are keyed so re-PUTting the same batch is safe
  2. Re-authenticate if the status indicates token expiry (401/403)
  3. Check for conflicts if another device synced the same keys (409) and re-download first
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src-rust/crates/core/src/settings_sync.rs:318 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/5e9462266bc002fe. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/core/src/settings_sync.rs:318

        debug!(count = changed.len(), "Settings sync: uploading changed entries");
        self.put_entries(changed).await
    }

    async fn put_entries(&self, entries: HashMap<String, String>) -> Result<()> {
        let body = serde_json::json!({ "entries": entries });
        let resp = self
            .http
            .put(self.endpoint())
            .header("Authorization", format!("Bearer {}", self.oauth_token))
            .header("anthropic-beta", "oauth-2025-04-20")
            .header("Content-Type", "application/json")
            .json(&body)
            .send()
            .await?;

        let status = resp.status().as_u16();
        if !(200..300).contains(&status) {
            anyhow::bail!("Settings sync upload: unexpected status {}", status);
        }
        Ok(())
    }

    // -----------------------------------------------------------------------
    // Fire-and-forget background upload (called from startup)
    // -----------------------------------------------------------------------

    /// Spawn a fire-and-forget upload task. Errors are logged but not propagated.
    ///
    /// Call this right after auth is established.  The task will:
    ///   1. Read local settings and AGENTS.md files
    ///   2. Fetch current remote state for diffing
    ///   3. Upload only changed entries
    pub fn upload_in_background(token: String, base_url: String) {
        tokio::spawn(async move {
            let mgr = SettingsSyncManager::new(token, base_url);
            let entries = collect_local_entries(None).await;

View on GitHub (pinned to b0637c97ec)