{"record":{"id":"125f6ac4f8420410","repo":"Wei-Shaw/sub2api","slug":"agent-identity-private-key","errorCode":null,"errorMessage":"agent identity private key 格式无效","messagePattern":"agent identity private key 格式无效","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/internal/handler/admin/account_codex_import.go","lineNumber":522,"sourceCode":"\tcase map[string]any:\n\t\tif agentIdentity, ok := firstCodexMap(raw, []string{\"agent_identity\"}, []string{\"agentIdentity\"}); ok || strings.EqualFold(firstCodexString(raw, []string{\"auth_mode\"}, []string{\"authMode\"}), service.OpenAIAuthModeAgentIdentity) {\n\t\t\tif !ok {\n\t\t\t\tagentIdentity = raw\n\t\t\t}\n\t\t\titem.IsAgentIdentity = true\n\t\t\titem.AgentRuntimeID = firstCodexString(agentIdentity, []string{\"agent_runtime_id\"}, []string{\"agentRuntimeId\"})\n\t\t\titem.AgentPrivateKey = firstCodexString(agentIdentity, []string{\"agent_private_key\"}, []string{\"agentPrivateKey\"})\n\t\t\titem.AgentTaskID = firstCodexString(agentIdentity, []string{\"task_id\"}, []string{\"taskId\"})\n\t\t\titem.AccountID = firstCodexString(agentIdentity, []string{\"account_id\"}, []string{\"accountId\"})\n\t\t\titem.UserID = firstCodexString(agentIdentity, []string{\"chatgpt_user_id\"}, []string{\"chatgptUserId\"})\n\t\t\titem.Email = firstCodexString(agentIdentity, []string{\"email\"})\n\t\t\titem.PlanType = firstCodexString(agentIdentity, []string{\"plan_type\"}, []string{\"planType\"})\n\t\t\titem.AgentFedRAMP = firstCodexBool(agentIdentity, []string{\"chatgpt_account_is_fedramp\"}, []string{\"chatgptAccountIsFedramp\"})\n\t\t\tif item.AgentRuntimeID == \"\" || item.AgentPrivateKey == \"\" || item.AccountID == \"\" || item.UserID == \"\" {\n\t\t\t\treturn nil, errors.New(\"agent identity 缺少必要字段\")\n\t\t\t}\n\t\t\tif err := service.ValidateOpenAIAgentIdentityPrivateKey(item.AgentPrivateKey); err != nil {\n\t\t\t\treturn nil, errors.New(\"agent identity private key 格式无效\")\n\t\t\t}\n\t\t\titem.Credentials[\"auth_mode\"] = service.OpenAIAuthModeAgentIdentity\n\t\t\titem.Credentials[\"agent_runtime_id\"] = item.AgentRuntimeID\n\t\t\titem.Credentials[\"agent_private_key\"] = item.AgentPrivateKey\n\t\t\titem.Credentials[\"chatgpt_account_id\"] = item.AccountID\n\t\t\titem.Credentials[\"chatgpt_user_id\"] = item.UserID\n\t\t\titem.Credentials[\"chatgpt_account_is_fedramp\"] = item.AgentFedRAMP\n\t\t\tsetCodexCredentialIfNotEmpty(item.Credentials, \"task_id\", item.AgentTaskID)\n\t\t\tsetCodexCredentialIfNotEmpty(item.Credentials, \"email\", item.Email)\n\t\t\tsetCodexCredentialIfNotEmpty(item.Credentials, \"plan_type\", item.PlanType)\n\t\t\tif item.AgentTaskID == \"\" {\n\t\t\t\titem.WarningTexts = append(item.WarningTexts, \"未包含 task_id，首次请求会使用现有 runtime 注册新 task\")\n\t\t\t}\n\t\t\titem.IdentityKeys = buildCodexAgentIdentityKeys(item.AccountID)\n\t\t\titem.Name = buildCodexImportAccountName(item, entry.Index)\n\t\t\treturn item, nil\n\t\t}\n\t\titem.AccessToken = firstCodexString(raw,","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/Wei-Shaw/sub2api/blob/073e92d17178a1ccdb0a27017f572f10c9c7ab62/backend/internal/handler/admin/account_codex_import.go#L504-L540","documentation":"Returned at backend/internal/handler/admin/account_codex_import.go:522 when all four mandatory agent-identity fields are present but service.ValidateOpenAIAgentIdentityPrivateKey rejects the private key string — the key is not parseable as the expected OpenAI agent-identity key format (wrong PEM/encoding, truncated, or corrupted). It wraps the underlying validation failure into a generic Chinese-language message.","triggerScenarios":"Importing an agent identity whose agent_private_key is malformed: not valid PEM, wrong key type, base64-corrupted body, missing header/footer lines, or a key copied with line breaks mangled by clipboard/JSON escaping.","commonSituations":"Copying the key from a terminal and losing the last line; pasting through a tool that wraps or escapes newlines; exporting from a different OpenAI tool version with another key format; trailing whitespace or BOM characters included in the string.","solutions":["Re-export the agent identity from its source and import the file unmodified rather than copying the key by hand.","Verify the key is a complete, valid PEM block (correct BEGIN/END lines, intact base64) before import.","Check the JSON file for escaped or doubled newlines inside agent_private_key (e.g. '\\n' vs literal newlines) and fix the encoding.","Confirm the tool version that produced the key matches the format ValidateOpenAIAgentIdentityPrivateKey expects."],"exampleFix":"// before\n\"agent_private_key\": \"-----BEGIN PRIVATE KEY----- MIIEv... (single line, newlines stripped)\n\n// after\n\"agent_private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADAN...\\n-----END PRIVATE KEY-----\\n\"","handlingStrategy":"validation","validationCode":"function isValidPemPrivateKey(key: string): boolean {\n  return /-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]+-----END [A-Z ]*PRIVATE KEY-----/.test(key.trim())\n}\n// Go callers can call the same validator the handler uses:\nif err := service.ValidateOpenAIAgentIdentityPrivateKey(key); err != nil {\n    // reject before persisting\n}","typeGuard":null,"tryCatchPattern":"if err := service.ValidateOpenAIAgentIdentityPrivateKey(item.AgentPrivateKey); err != nil {\n    return fmt.Errorf(\"entry %d: agent identity private key 格式无效: %w\", entry.Index, err)\n}","preventionTips":["Never retype or re-wrap private keys by hand; always transfer via file.","Keep the key as a complete PEM block with real newlines preserved in JSON (escaped \\n).","Run ValidateOpenAIAgentIdentityPrivateKey in your own tooling before submission.","After any format migration between OpenAI tool versions, re-export identities fresh."],"tags":["admin","import","agent-identity","private-key","validation","backend","codex"],"backgroundTag":null,"analyzedSha":"073e92d17178a1ccdb0a27017f572f10c9c7ab62","analyzedAt":"2026-08-15T14:33:00.750Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}