Summary
After a token rotation or session expiry (the failure class behind #178 / #179, and reproducible today: a fresh relayfile tree against rw_fc7b534b returned http 401 unauthorized: Token has expired), relayfile status continues to print provider lag / daemon state with no indication that the reason the daemon is silent is that its in-memory credentials are stale. Operators have to guess that re-login is the remedy.
Code references
cmd/relayfile-cli/main.go:4404 — runStatus
cmd/relayfile-cli/main.go:4421 — loads credentials but never inspects their freshness
cmd/relayfile-cli/main.go:4438 — calls fetchWorkspaceSyncStatus; a 401 here propagates as a generic error, never as "stale creds"
cmd/relayfile-cli/main.go:4486-4505 — output block: prints local mirror / daemon line / bootstrap / stall / pending counts — no auth section
cmd/relayfile-cli/main.go:980 — ErrCloudRefreshExpired = "cloud session expired. Run 'relayfile login' to sign in again." already exists but is not consulted by runStatus.
Expected vs Actual
- Expected:
relayfile status shows an auth: line (or warning) when (a) the cloud access token is past accessTokenExpiresAt, or (b) the refresh token is past refreshTokenExpiresAt, or (c) credentials.json mtime is older than the running daemon's start time (which indicates a re-login happened after the daemon booted and the daemon is now stale — see the co-filed login co-refresh issue).
- Actual: No such line. 401s during status are surfaced as raw errors or mask as a silent provider stall.
Suggested fix direction
Minimal additions, no new endpoint required:
- In
runStatus, call loadCloudCredentials() and compare accessTokenExpiresAt / refreshTokenExpiresAt against time.Now(). Render one of: auth: ok, auth: access token expires in <Xm>, auth: cloud session expired — run 'relayfile login'.
- Read the daemon PID's start time (already available via
readDaemonPID(record.LocalDir) at line 4453) and compare with credentials.json / cloud-credentials.json mtimes; if either cred file is newer than the daemon start, print auth: daemon predates last login — restart the daemon.
- Surface
ErrCloudRefreshExpired explicitly when status sees a 401 from fetchWorkspaceSyncStatus.
Related
Summary
After a token rotation or session expiry (the failure class behind #178 / #179, and reproducible today: a fresh
relayfile treeagainstrw_fc7b534breturnedhttp 401 unauthorized: Token has expired),relayfile statuscontinues to print provider lag / daemon state with no indication that the reason the daemon is silent is that its in-memory credentials are stale. Operators have to guess that re-login is the remedy.Code references
cmd/relayfile-cli/main.go:4404—runStatuscmd/relayfile-cli/main.go:4421— loads credentials but never inspects their freshnesscmd/relayfile-cli/main.go:4438— callsfetchWorkspaceSyncStatus; a 401 here propagates as a generic error, never as "stale creds"cmd/relayfile-cli/main.go:4486-4505— output block: prints local mirror / daemon line / bootstrap / stall / pending counts — no auth sectioncmd/relayfile-cli/main.go:980—ErrCloudRefreshExpired = "cloud session expired. Run 'relayfile login' to sign in again."already exists but is not consulted byrunStatus.Expected vs Actual
relayfile statusshows anauth:line (or warning) when (a) the cloud access token is pastaccessTokenExpiresAt, or (b) the refresh token is pastrefreshTokenExpiresAt, or (c)credentials.jsonmtime is older than the running daemon's start time (which indicates a re-login happened after the daemon booted and the daemon is now stale — see the co-filed login co-refresh issue).Suggested fix direction
Minimal additions, no new endpoint required:
runStatus, callloadCloudCredentials()and compareaccessTokenExpiresAt/refreshTokenExpiresAtagainsttime.Now(). Render one of:auth: ok,auth: access token expires in <Xm>,auth: cloud session expired — run 'relayfile login'.readDaemonPID(record.LocalDir)at line 4453) and compare withcredentials.json/cloud-credentials.jsonmtimes; if either cred file is newer than the daemon start, printauth: daemon predates last login — restart the daemon.ErrCloudRefreshExpiredexplicitly when status sees a 401 fromfetchWorkspaceSyncStatus.Related
relayfile login only refreshes one of two credential files— the cred-file split is the reason daemon ↔ cred-file mtime drift is even possible.