openclaw/openclaw · error
Codex app-server conversation binding requires a binding id
Error message
Codex app-server conversation binding requires a binding id
What it means
Thrown by bindingStoreKey when identity.kind !== 'session' (i.e. a conversation identity) but identity.bindingId (trimmed) is empty. Conversation-scoped bindings are keyed by bindingId; without it the store key 'conversation:<id>' cannot be formed.
Source
Thrown at extensions/codex/src/app-server/session-binding.ts:1316
const rawAgentId = identity.agentId.trim();
const sessionId = identity.sessionId.trim();
if (!rawAgentId) {
throw new Error("Codex app-server binding requires an agent id");
}
if (!sessionId) {
throw new Error("Codex app-server binding requires a session id");
}
const agentId = resolveSessionAgentIds({ agentId: rawAgentId }).sessionAgentId;
const sessionKey = identity.sessionKey?.trim();
if (sessionKey) {
const digest = createHash("sha256").update(sessionKey).digest("base64url");
return `session-key:${agentId}:${digest}`;
}
return `session:${agentId}:${sessionId}`;
}
const bindingId = identity.bindingId.trim();
if (!bindingId) {
throw new Error("Codex app-server conversation binding requires a binding id");
}
return `conversation:${bindingId}`;
}
export function readStoredCodexAppServerBinding(
value: unknown,
): StoredCodexAppServerBinding | undefined {
const result = storedBindingSchema.safeParse(value);
return result.success
? (stripUndefinedValue(result.data) as StoredCodexAppServerBinding)
: undefined;
}
function storedSessionGeneration(
identity: CodexAppServerBindingIdentity,
current: StoredCodexAppServerBinding | undefined,
): { sessionId?: string } {
if (identity.kind === "session") {View on GitHub (pinned to 01804a7531)
Solutions
- Set identity.bindingId to a non-empty conversation binding identifier before any binding-store call.
- If you meant to use a session-scoped binding, set kind: 'session' with agentId and sessionId instead.
- Add a constructor-time assertion that bindingId is non-empty for conversation identities.
- Trace the identity's origin and ensure bindingId is populated upstream.
Example fix
// before
const identity = { kind: 'conversation', bindingId: '' };
// after
const identity = { kind: 'conversation', bindingId: conversation.bindingId }; Defensive patterns
Strategy: validation
Validate before calling
function hasBindingId(identity: CodexAppServerBindingIdentity): boolean {
return identity.kind !== 'conversation' || (typeof identity.bindingId === 'string' && identity.bindingId.trim() !== '');
}
if (!hasBindingId(identity)) {
// do not call the binding store; populate bindingId or switch to kind: 'session' Type guard
export function conversationIdentityHasBindingId(i: CodexAppServerBindingIdentity): boolean {
return i.kind !== 'conversation' || (typeof i.bindingId === 'string' && i.bindingId.trim() !== '');
} Try / catch
try {
const key = bindingStoreKey(identity);
} catch (error) {
if (error instanceof Error && /conversation binding requires a binding id/.test(error.message)) {
// caller bug: populate identity.bindingId before any binding-store call
}
throw error;
} Prevention
- Populate bindingId when constructing a conversation identity.
- If you meant session-scoped, use kind: 'session' with agentId + sessionId.
- Add a constructor-time assertion for non-empty bindingId on conversation identities.
- Trace identity construction to ensure bindingId is sourced from a durable conversation reference.
When it happens
Trigger: Calling any binding-store operation with a conversation identity whose bindingId is blank/whitespace. bindingStoreKey runs first and rejects before state access.
Common situations: A caller constructing a conversation identity without a bindingId; a refactoring that dropped the bindingId field; using the conversation-kind path without a durable conversation/binding reference.
Related errors
- Codex app-server binding requires an agent id
- Codex app-server binding requires a session id
- Codex session generation adoption requires the previous sess
- This automation was authorized for Codex profile ${scheduled
- Refusing to replace supervised Codex thread ${threadId} whil
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/47d2ac3384f3ae75.
Report an issue: GitHub.