{"record":{"id":"6c4f0b80ea22d2e3","repo":"Hmbown/CodeWhale","slug":"create-isolated-input-pipe","errorCode":null,"errorMessage":"create isolated input pipe","messagePattern":"create isolated input pipe","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/palette/src/osc11_tests.rs","lineNumber":43,"sourceCode":"            reply: b\"\\x1b]11;rgb:1e1e/1e1e/1e1e\",\n            csi: false,\n        },\n        Case {\n            query: b\"\\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\\x1b\\\\\",\n            response: b\"\\x1b_Gi=31;OK\\x1b\\\\\",\n            reply: b\"\\x1b_Gi=31;OK\",\n            csi: false,\n        },\n        Case {\n            query: b\"\\x1b[c\",\n            response: b\"\\x1b[?62;4c\",\n            reply: b\"\\x1b[?62;4c\",\n            csi: true,\n        },\n    ];\n\n    for case in cases {\n        let (mut reader, mut writer) = std::io::pipe().expect(\"create isolated input pipe\");\n        let prefix = b\"/plu\";\n        let suffix = b\"gin list\\r\";\n        let burst = [prefix.as_slice(), case.response, suffix.as_slice()].concat();\n        assert_eq!(\n            writer.write(&burst).expect(\"write one input burst\"),\n            burst.len()\n        );\n\n        // Keep the writer open: a buffered read-ahead must not be rescued by\n        // EOF/readable-HUP while the real tty would have no new bytes ready.\n        let (answered, reply, carried) = read_terminal_reply(\n            reader.as_raw_fd(),\n            case.query,\n            Duration::from_secs(1),\n            case.csi,\n        );\n        drop(writer);\n        let mut remaining = Vec::new();","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/palette/src/osc11_tests.rs#L25-L61","documentation":"`terminal_reply_reader_leaves_one_burst_typed_suffix_on_the_descriptor` creates a test pipe with `std::io::pipe().expect(\"create isolated input pipe\")`. The expect panics if the OS refuses to create the pipe pair (out of file descriptors, or a platform without `pipe2` support). The pipe stands in for a tty to test that terminal device-attributes replies are detected and the typed suffix stays buffered.","triggerScenarios":"Running the test with the process file-descriptor limit exhausted; running on a platform/runtime where `std::io::pipe` is unavailable (pre-1.87 Rust std or restricted sandboxes); ulimit -n set extremely low in CI containers.","commonSituations":"CI containers with tiny fd limits or fd leaks from earlier tests; older toolchains without `std::io::pipe` (stabilized in Rust 1.87); seccomp/apparmor policies blocking pipe syscalls.","solutions":["Raise the fd limit (`ulimit -n 1024` or the CI equivalent)","Check for fd leaks in earlier tests (pipes/sockets never dropped)","Upgrade the Rust toolchain to one where `std::io::pipe` is stable","Verify the sandbox/seccomp profile permits pipe creation"],"exampleFix":"// before\nlet (mut reader, mut writer) = std::io::pipe().expect(\"create isolated input pipe\");\n// after\nlet (mut reader, mut writer) = std::io::pipe()\n    .unwrap_or_else(|e| panic!(\"pipe creation failed (fd limit?): {e}\"));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let (reader, writer) = std::io::pipe()\n    .unwrap_or_else(|e| panic!(\"cannot create test pipe: {e} (check ulimit -n)\"));","preventionTips":["Check `ulimit -n` in CI before running fd-heavy test suites","Drop pipe endpoints promptly; never leak readers/writers across tests","Pin a Rust toolchain ≥1.87 where `std::io::pipe` is stable"],"tags":["rust","io","pipe","test"],"backgroundTag":"file-open-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}