{"record":{"id":"5f2bf7027a9dfd10","repo":"nikivdev/code","slug":"prompt-is-empty","errorCode":null,"errorMessage":"prompt is empty","messagePattern":"prompt is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ai_everruns.rs","lineNumber":92,"sourceCode":"        Err(err) => rl_signals::emit(json!({\n            \"event_type\": \"everruns.run_failed\",\n            \"runtime\": \"everruns\",\n            \"session_id\": session_id,\n            \"input_message_id\": message_id,\n            \"ok\": false,\n            \"runtime_ms\": runtime_ms,\n            \"error\": err.to_string(),\n            \"error_class\": classify_error_text(&err.to_string()),\n        })),\n    }\n    result\n}\n\nfn resolve_prompt(opts: &AiEverrunsOpts) -> Result<String> {\n    if !opts.prompt.is_empty() {\n        let joined = opts.prompt.join(\" \").trim().to_string();\n        if joined.is_empty() {\n            bail!(\"prompt is empty\");\n        };\n        return Ok(joined);\n    }\n\n    if io::stdin().is_terminal() {\n        bail!(\"missing prompt. Usage: f ai everruns \\\"your prompt\\\"\");\n    }\n\n    let mut buf = String::new();\n    io::stdin()\n        .read_to_string(&mut buf)\n        .context(\"failed to read prompt from stdin\")?;\n    let prompt = buf.trim().to_string();\n    if prompt.is_empty() {\n        bail!(\"prompt from stdin is empty\");\n    }\n    Ok(prompt)\n}","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ai_everruns.rs#L74-L110","documentation":"Thrown by resolve_prompt() in the `f ai everruns` command when a prompt argument list was supplied but joining its parts and trimming yields an empty string. The guard prevents launching everruns with a blank prompt, which would be meaningless work for the AI runner.","triggerScenarios":"Calling `f ai everruns \"\"` or `f ai everruns \"   \"` — opts.prompt is non-empty as a Vec (so the stdin path is skipped) but the joined, trimmed result is empty.","commonSituations":"Shell variables expanding to empty (PROMPT=\"$UNSET\"); quoting mistakes passing only whitespace; scripts forwarding an optional prompt arg that was blank; CI templates with an unfilled placeholder.","solutions":["Pass a non-empty quoted prompt as the argument","Check the variable feeding the prompt is actually set and non-blank","Omit the argument entirely to fall back to stdin input instead of passing empty quotes","In scripts, guard with [ -n \"$PROMPT\" ] before invoking the command"],"exampleFix":"// before\nf ai everruns \"$PROMPT\"      # PROMPT=\"\"\n// after\nPROMPT=\"summarize the last run\"\nf ai everruns \"$PROMPT\"","handlingStrategy":"validation","validationCode":"# shell: refuse to invoke with a blank prompt\n[ -n \"${PROMPT//[[:space:]]/}\" ] || { echo \"prompt must be non-empty\"; exit 1; }\nf ai everruns \"$PROMPT\"","typeGuard":null,"tryCatchPattern":"// caller-side: validate before invoking; error is deterministic so no catch needed\nlet joined = args.join(\" \").trim().to_string();\nanyhow::ensure!(!joined.is_empty(), \"refusing to call `f ai everruns` with a blank prompt\");\nrun_everruns(&joined)?;","preventionTips":["Guard shell variables with ${PROMPT:?} before interpolation","Quote the whole prompt as one argument","In CI, fail fast when a prompt template variable is unfilled","Trim and assert non-empty before passing user-supplied prompts"],"tags":["prompt","validation","cli","empty-input"],"backgroundTag":"empty-prompt","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}