repos bind/update permanently fails once a repo's last announcement is >15 min old
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Start with crates/buzz-cli/src/commands/repos.rs:147-154 and compare its timestamp handling with the drift check in crates/buzz-relay/src/handlers/ingest.rs:1976-1983. Reproduce the update after a repo announcement is over 15 minutes old, then verify that bind and protect updates succeed while preserving the observed-head ordering invariant.
Written by the indexing model from the issue text.
Description
Describe the bug
buzz repos bind (and any other repo-metadata update going through the same helper, e.g. repos protect) can permanently fail with:
relay error 400: invalid: event timestamp too far from server time
This is not a client-clock issue — it's a logic bug in how the CLI advances the repo announcement's created_at, combined with the relay's timestamp-drift check.
crates/buzz-cli/src/commands/repos.rs:147-154 computes the updated event's created_at as existing_repo.created_at + 1 (never wall-clock time), specifically to stop a delayed writer from clobbering a newer concurrent update:
// Advance only the observed head. Using wall-clock time here would let a
// delayed writer leapfrog an intervening update and silently erase metadata.
let next_created_at = existing
.created_at
.as_secs()
.checked_add(1)
...
crates/buzz-relay/src/handlers/ingest.rs:1976-1983 rejects any incoming event whose created_at is more than MAX_TIMESTAMP_DRIFT_SECS = 900 (15 minutes) away from the relay's own clock:
const MAX_TIMESTAMP_DRIFT_SECS: i64 = 900; // ±15 minutes
let now = chrono::Utc::now().timestamp();
let event_ts = event.created_at.as_secs() as i64;
if (event_ts - now).abs() > MAX_TIMESTAMP_DRIFT_SECS {
return Err(IngestError::Rejected(
"invalid: event timestamp too far from server time".into(),
));
}
If a repo's most recent announcement is already older than 15 minutes, existing_created_at + 1 is also older than 15 minutes, so the relay rejects it every time. The repo is then permanently stuck: no bind/protect update can ever succeed again through this code path, regardless of who signs it or how many times it's retried.
Steps to reproduce
- Announce a repo with
buzz repos create. - Wait more than 15 minutes without touching it again.
- Run
buzz repos bind --id <id> --channel <uuid>(orrepos protect). - See error: non-retryable
relay error 400: invalid: event timestamp too far from server time.
Expected behavior
The update should succeed regardless of how old the repo's last announcement is, since the caller's request is well within the relay's acceptable clock drift.
Suggested fix: use max(now, existing_created_at + 1) instead of existing_created_at + 1 alone in repos.rs. This still satisfies the "advance past the observed head" invariant the comment describes, while keeping the timestamp within the relay's accepted drift window.
Version and platform
- Buzz version: buzz-cli workspace
0.1.0(commit538e5e1, 2026-08-10) - OS: macOS 15.6 (24G84)
Logs / additional context
None beyond the inline snippets above; no screenshots (CLI-only repro).
- Dominant language
- Rust
- Stars
- 33.7k
- Forks
- 4.4k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 239
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from block/buzz
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
workflow_sink's mention parser never masks code regions — @name inside a code span wakes the agent Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 Half a day Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100