{"record":{"id":"16cfd223092f7084","repo":"wavetermdev/waveterm","slug":"stdin-can-only-be-used-once","errorCode":null,"errorMessage":"stdin (-) can only be used once","messagePattern":"stdin \\(-\\) can only be used once","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-ai.go","lineNumber":97,"sourceCode":"\tconst maxFileCount = 15\n\tconst rpcTimeout = 30000\n\n\tvar allFiles []wshrpc.AIAttachedFile\n\tvar stdinUsed bool\n\n\tif len(args) > maxFileCount {\n\t\treturn fmt.Errorf(\"too many files (maximum %d files allowed)\", maxFileCount)\n\t}\n\n\tfor _, filePath := range args {\n\t\tvar data []byte\n\t\tvar fileName string\n\t\tvar mimeType string\n\t\tvar err error\n\n\t\tif filePath == \"-\" {\n\t\t\tif stdinUsed {\n\t\t\t\treturn fmt.Errorf(\"stdin (-) can only be used once\")\n\t\t\t}\n\t\t\tstdinUsed = true\n\n\t\t\tdata, err = io.ReadAll(os.Stdin)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"reading from stdin: %w\", err)\n\t\t\t}\n\t\t\tfileName = \"stdin\"\n\t\t\tmimeType = \"text/plain\"\n\t\t} else {\n\t\t\tfileInfo, err := os.Stat(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"accessing file %s: %w\", filePath, err)\n\t\t\t}\n\t\t\tabsPath, err := filepath.Abs(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"getting absolute path for %s: %w\", filePath, err)\n\t\t\t}","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-ai.go#L79-L115","documentation":"The `wsh ai` command allows the special `-` argument (stdin) at most once. A stdinUsed flag guards this; passing a second `-` returns this error before reading anything, because each `-` would require a second sequential read of os.Stdin which the command does not support.","triggerScenarios":"Running e.g. `wsh ai - - file.txt` or `cat a | wsh ai - -`, i.e. two or more literal `-` arguments in the same invocation.","commonSituations":"Users assuming `-` behaves like `cat` (repeatable), templated commands that inject `-` per input stream, copy-pasted command lines with duplicated placeholders.","solutions":["Remove duplicate `-` arguments; keep exactly one `-`.","Concatenate multiple stdin sources first: `cat a b | wsh ai -`.","If second input is a file, pass its path instead of `-`.","For scripting, deduplicate the args list before invoking wsh ai."],"exampleFix":"// before\n$ echo x | wsh ai - - notes.txt\n// after\n$ echo x | wsh ai - notes.txt","handlingStrategy":"validation","validationCode":"count=$(printf '%s\\n' \"$@\" | grep -cx -- '-' || true)\nif [ \"$count\" -gt 1 ]; then\n  echo \"wsh ai accepts at most one '-' (stdin) argument\" >&2\n  exit 1\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat `-` as a singleton placeholder in any command template that builds wsh ai invocations.","Concatenate multiple streams into one pipe: `cat a b | wsh ai -`.","Deduplicate args programmatically before calling wsh ai in scripts."],"tags":["cli","stdin","argument-validation","wsh"],"backgroundTag":"stdin-passed-more-than-once","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}