{"record":{"id":"c6311dc09b9afe69","repo":"openai/codex","slug":"remote-control-client-list-requires-environmentid","errorCode":null,"errorMessage":"remote control client list requires environmentId","messagePattern":"remote control client list requires environmentId","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/app-server-transport/src/transport/remote_control/clients.rs","lineNumber":75,"sourceCode":"    },\n    Revoke {\n        url: &'a Url,\n    },\n}\n\nstruct ClientManagementResponse {\n    status: axum::http::StatusCode,\n    headers: HeaderMap,\n    body: Vec<u8>,\n}\n\npub(super) async fn list_remote_control_clients(\n    remote_control_url: &str,\n    auth_manager: &Arc<AuthManager>,\n    params: RemoteControlClientsListParams,\n) -> io::Result<RemoteControlClientsListResponse> {\n    if params.environment_id.is_empty() {\n        return Err(io::Error::new(\n            ErrorKind::InvalidInput,\n            \"remote control client list requires environmentId\",\n        ));\n    }\n    if params\n        .limit\n        .is_some_and(|limit| !(1..=100).contains(&limit))\n    {\n        return Err(io::Error::new(\n            ErrorKind::InvalidInput,\n            \"remote control client list limit must be between 1 and 100\",\n        ));\n    }\n    let url = environment_clients_url(remote_control_url, &params.environment_id)?;\n    let response = send_client_management_request(\n        auth_manager,\n        ClientManagementRequest::List {\n            url: &url,","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/app-server-transport/src/transport/remote_control/clients.rs#L57-L93","documentation":"list_remote_control_clients rejects RemoteControlClientsListParams.environment_id when it is an empty string, failing fast with InvalidInput before building the environments/{id}/clients URL. The environment id scopes the client list to one remote-control environment, so an empty value has no valid server-side interpretation.","triggerScenarios":"Calling the remote-control client list with environment_id defaulted or blank — String::new() in Rust default-struct initialization, a JSON request that sent {\"environmentId\": \"\"}, or listing before the environment id was obtained from the pairing/enrollment flow.","commonSituations":"TS/JSON clients that model environmentId as optional and serialize the empty string; racing the list call before pairing status delivered the environment id; Rust callers filling params with ..Default::default() and forgetting the field.","solutions":["Supply the environmentId returned by the pairing/enrollment flow (pairing status response)","Queue or skip the list call client-side until an environment id is known","If your JSON payload genuinely lacks the field, fix the producer — the v2 API requires it non-empty"],"exampleFix":"// before\nlet params = RemoteControlClientsListParams {\n    environment_id: String::new(),\n    ..Default::default()\n};\nlist_remote_control_clients(url, &auth_manager, params).await\n// Err: remote control client list requires environmentId\n\n// after\nlet params = RemoteControlClientsListParams {\n    environment_id: environment_id.clone(),\n    ..Default::default()\n};\nlist_remote_control_clients(url, &auth_manager, params).await  // Ok","handlingStrategy":"validation","validationCode":"fn can_list_clients(p: &RemoteControlClientsListParams) -> bool {\n    !p.environment_id.is_empty()\n}","typeGuard":"function hasEnvironmentId(p: RemoteControlClientsListParams): p is RemoteControlClientsListParams & { environmentId: string } {\n  return typeof p.environmentId === 'string' && p.environmentId.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Mark environmentId required in generated TS types instead of optional","Source environment ids only from pairing status responses, never free-text input","Assert non-empty in integration tests so regressions fail as test errors, not runtime InvalidInput"],"tags":["validation","remote-control","api-params","invalid-input"],"backgroundTag":"missing-required-parameter","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}