关于codex会话400问题:bad response status code 400(request id:...)

Nein 2026-09-07 21:05 1

在使用codex处理问题的时候,有时候切换渠道,新渠道会报错:bad response status code 400(request id:…)


本质原因是新渠道无法识别这个request id,新渠道做了缓存的处理,比如大善人的any。

解决方案:

1、开新会话,并把旧会话request id告诉agent,让agent读取旧会话内容然后继续。

2、用脚本清理本地所有request id,重新使用会自动生成新的request id,下面是我自己的一个python脚本,是删除本地的所有request id的,有需要可以用,脚本暂时是清理本地所有会话的,所以用的时候,要让需要处理的会话停止。(codex cli要退出会话,不然会占用文件导致修改失败)




python脚本代码

from pathlib import Path
from datetime import datetime
import json
import shutil
import os

ROOT = Path.home() / ".codex" / "sessions"

if not ROOT.exists():
raise SystemExit(f"Codex sessions directory not found: {ROOT}")

stamp = datetime.now().strftime("%Y%m%d-%H%M%S")
BACKUP_ROOT = ROOT.parent / f"sessions-backup-{stamp}"

print("=" * 100)
print("Codex Session Repair")
print("=" * 100)
print(f"Sessions : {ROOT}")
print(f"Backup : {BACKUP_ROOT}")
print()

# ----------------------------------------------------------------------
# 1. 完整备份整个 sessions 目录
# ----------------------------------------------------------------------

print("Creating full backup...")

shutil.copytree(ROOT, BACKUP_ROOT)

print(f"Backup created: {BACKUP_ROOT}")
print()

# ----------------------------------------------------------------------
# 2. 找到所有 rollout
# ----------------------------------------------------------------------

files = sorted(ROOT.rglob("rollout-*.jsonl"))

if not files:
raise SystemExit("No rollout files found.")

print(f"Found {len(files)} rollout files.")
print()

total_files = 0
changed_files = 0

total_reasoning = 0
removed_reasoning_encrypted = 0

total_compaction = 0
removed_compaction_encrypted = 0

# ----------------------------------------------------------------------
# 3. 判断 / 修复 encrypted_content
#
# 只处理:
# type=response_item, payload.type=reasoning
# type=response_item, payload.type=compaction
#
# 同时递归处理 compaction 中嵌套的 replacement_history。
# ----------------------------------------------------------------------

def sanitize(node):
"""
Remove provider-specific encrypted_content only from
reasoning / compaction structures.

Returns:
(new_node, changed, reasoning_count, reasoning_removed,
compaction_count, compaction_removed)
"""

changed = False
reasoning_count = 0
reasoning_removed = 0
compaction_count = 0
compaction_removed = 0

if isinstance(node, dict):
# 判断当前节点是不是 reasoning / compaction
node_type = node.get("type")

is_reasoning = node_type == "reasoning"
is_compaction = node_type == "compaction"

if is_reasoning:
reasoning_count += 1

if "encrypted_content" in node:
del node["encrypted_content"]
changed = True
reasoning_removed += 1

if is_compaction:
compaction_count += 1

if "encrypted_content" in node:
del node["encrypted_content"]
changed = True
compaction_removed += 1

# 继续递归处理所有子节点
for key in list(node.keys()):
new_value, c, rc, rr, cc, cr = sanitize(node[key])
node[key] = new_value

changed = changed or c
reasoning_count += rc
reasoning_removed += rr
compaction_count += cc
compaction_removed += cr

return (
node,
changed,
reasoning_count,
reasoning_removed,
compaction_count,
compaction_removed,
)

elif isinstance(node, list):
new_list = []

for item in node:
new_item, c, rc, rr, cc, cr = sanitize(item)

new_list.append(new_item)

changed = changed or c
reasoning_count += rc
reasoning_removed += rr
compaction_count += cc
compaction_removed += cr

return (
new_list,
changed,
reasoning_count,
reasoning_removed,
compaction_count,
compaction_removed,
)

return (
node,
False,
0,
0,
0,
0,
)

# ----------------------------------------------------------------------
# 4. 逐个修复
# ----------------------------------------------------------------------

for src in files:
total_files += 1

tmp = src.with_suffix(".repairing.jsonl")

file_changed = False
file_reasoning = 0
file_reasoning_removed = 0
file_compaction = 0
file_compaction_removed = 0

line_count = 0

try:
with (
src.open("r", encoding="utf-8", errors="strict") as fin,
tmp.open("w", encoding="utf-8", newline="\n") as fout,
):
for line_no, line in enumerate(fin, 1):
line_count += 1

try:
obj = json.loads(line)
except Exception as e:
raise RuntimeError(
f"Invalid JSON: {src} line {line_no}: {e}"
)

(
obj,
changed,
rc,
rr,
cc,
cr,
) = sanitize(obj)

file_changed = file_changed or changed
file_reasoning += rc
file_reasoning_removed += rr
file_compaction += cc
file_compaction_removed += cr

fout.write(
json.dumps(
obj,
ensure_ascii=False,
separators=(",", ":"),
)
+ "\n"
)

# ------------------------------------------------------------------
# 5. 验证临时文件
# ------------------------------------------------------------------

with tmp.open("r", encoding="utf-8") as f:
for line_no, line in enumerate(f, 1):
try:
json.loads(line)
except Exception as e:
raise RuntimeError(
f"Validation failed: {tmp} line {line_no}: {e}"
)

# ------------------------------------------------------------------
# 6. 验证:目标结构里不能再存在 encrypted_content
# ------------------------------------------------------------------

remaining_encrypted = 0

with tmp.open("r", encoding="utf-8") as f:
for line in f:
obj = json.loads(line)

def count_target_encrypted(node):
count = 0

if isinstance(node, dict):
t = node.get("type")

if t in ("reasoning", "compaction"):
if "encrypted_content" in node:
count += 1

for value in node.values():
count += count_target_encrypted(value)

elif isinstance(node, list):
for value in node:
count += count_target_encrypted(value)

return count

remaining_encrypted += count_target_encrypted(obj)

if remaining_encrypted != 0:
raise RuntimeError(
f"Repair verification failed for {src}: "
f"{remaining_encrypted} encrypted fields remain."
)

# ------------------------------------------------------------------
# 7. 没修改就删除临时文件
# ------------------------------------------------------------------

if not file_changed:
tmp.unlink(missing_ok=True)

print(f"[SKIP] {src}")
print(" no provider-specific encrypted reasoning found")
print()

continue

# ------------------------------------------------------------------
# 8. 原子替换
# ------------------------------------------------------------------

os.replace(tmp, src)

changed_files += 1

total_reasoning += file_reasoning
removed_reasoning_encrypted += file_reasoning_removed

total_compaction += file_compaction
removed_compaction_encrypted += file_compaction_removed

print(f"[FIXED] {src}")
print(f" lines : {line_count:,}")
print(f" reasoning : {file_reasoning}")
print(f" reasoning encrypted : {file_reasoning_removed}")
print(f" compaction : {file_compaction}")
print(f" compaction encrypted : {file_compaction_removed}")
print()
except (PermissionError, OSError) as e:
tmp.unlink(missing_ok=True)
print(f"[SKIP - INACCESSIBLE] {src}")
print(f" Reason: {e}\n")
continue
except Exception:
tmp.unlink(missing_ok=True)
raise

# ----------------------------------------------------------------------
# 9. 最终结果
# ----------------------------------------------------------------------

print("=" * 100)
print("DONE")
print("=" * 100)
print(f"Total rollout files : {total_files}")
print(f"Changed files : {changed_files}")
print(f"Reasoning items : {total_reasoning}")
print(f"Reasoning encrypted rm : {removed_reasoning_encrypted}")
print(f"Compaction items : {total_compaction}")
print(f"Compaction encrypted rm : {removed_compaction_encrypted}")
print()
print(f"FULL BACKUP : {BACKUP_ROOT}")
print()
print("Original sessions were repaired in-place.")
print("Full backup is available for rollback.")


最新回复 (1)
  • 卖泡面 辣条 09-08 02:23
    1

    使用子智能体或者浏览器直接会报错

* 帖子来源Linux.do
返回