musistudio/claude-code-router · error
ARCHIVE_REPLAY_UNAVAILABLE
ARCHIVE_REPLAY_UNAVAILABLE
Error message
The gateway replay executor is not available.
What it means
Thrown when the replay path is entered but no replay executor was provided to the archive service. The executor is the component that actually re-issues the archived request to the upstream agent; without it, replay cannot proceed.
Source
Thrown at packages/core/src/gateway/context-archive.ts:235
throw contextArchiveError("ARCHIVE_INVALID_ARGUMENT", `${toolName} requires archive_id, session_token, and task.`);
}
const store = this.store(config);
const rootSnapshot = store.get(archiveId);
if (!rootSnapshot) {
throw contextArchiveError("ARCHIVE_NOT_FOUND", `Archive ${archiveId} does not exist or has expired.`);
}
if (rootSnapshot.expiresAt !== undefined && rootSnapshot.expiresAt <= Date.now()) {
throw contextArchiveError("ARCHIVE_EXPIRED", `Archive ${archiveId} has expired.`);
}
if (rootSnapshot.status !== "ready") {
throw contextArchiveError("ARCHIVE_NOT_READY", `Archive ${archiveId} is ${rootSnapshot.status}.`);
}
if (!constantTimeEqual(rootSnapshot.tokenHash, sha256(sessionToken))) {
throw contextArchiveError("ARCHIVE_ACCESS_DENIED", "The archive session token is invalid.");
}
if (!executor) {
throw contextArchiveError("ARCHIVE_REPLAY_UNAVAILABLE", "The gateway replay executor is not available.");
}
const lineage = store.lineage(archiveId, maxLineageReplayDepth);
const searchedGenerations: number[] = [];
let lastInsufficientAnswer: { answer: string; snapshot: ArchiveSnapshot } | undefined;
for (const snapshot of lineage) {
if (snapshot.expiresAt !== undefined && snapshot.expiresAt <= Date.now()) {
continue;
}
if (snapshot.status !== "ready") {
continue;
}
const answer = await replayArchiveSnapshot(snapshot, task, config, executor);
searchedGenerations.push(snapshot.generation);
if (isInsufficientArchiveAnswer(answer) && snapshot.parentArchiveId) {
lastInsufficientAnswer = { answer, snapshot };
continue;
}View on GitHub (pinned to 99f24806c6)
Solutions
- Provide/restore the replay executor when constructing the archive service
- Check the service construction path in your composition root or DI container for a missing/optional registration
- Add a startup assertion that the executor is bound before enabling the archive feature
Example fix
// before
const archive = new ContextArchive({ storagePath }); // no executor
await archive.ask(id, token, task); // ARCHIVE_REPLAY_UNAVAILABLE
// after
const archive = new ContextArchive({ storagePath }, replayExecutor);
await archive.ask(id, token, task); Defensive patterns
Strategy: validation
Validate before calling
if (!executor) throw new Error('replay executor required for archive replay');
const archive = new ContextArchive(config, executor); Type guard
function hasExecutor(x: unknown): x is ReplayExecutor {
return !!x && typeof x === 'object' && 'answer' in x;
} Try / catch
try { await archive.ask(id, token, task); }
catch (e) { if (e.code === 'ARCHIVE_REPLAY_UNAVAILABLE') { /* fail fast at startup instead */ } throw e; } Prevention
- Assert executor presence in your composition root at startup, not lazily at replay time
- Make the executor a required constructor parameter in your own wrapper
- Add an integration test that performs one full replay in CI
When it happens
Trigger: Constructing the ContextArchive service/gateway without wiring an executor (or passing undefined), then calling ask() on a valid, ready, token-matching archive.
Common situations: DI misconfiguration where the executor binding is optional and silently omitted; test harnesses constructing the service with partial dependencies; refactors that removed executor registration.
Related errors
- No Bot Gateway conversationRef is available for media respon
- Refusing to archive unknown legacy JSON config file: ${unsup
- ToolHub resolver requires TOOLHUB_OPENAI_API_KEY and TOOLHUB
- Video fallback model ${selector} uses ${target.protocol}, bu
- A media model must be selected.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/dfc7ab07faffd375.
Report an issue: GitHub.