{"record":{"id":"c11c0236ac5f2a74","repo":"Hmbown/CodeWhale","slug":"fleet-field-must-be-one-printable-line-no-longer","errorCode":null,"errorMessage":"fleet {field} must be one printable line no longer than {MAX_FLEET_NAME_BYTES} bytes","messagePattern":"fleet (.+?) must be one printable line no longer than (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/task_spec.rs","lineNumber":165,"sourceCode":"\nfn validate_fleet_identity(field: &str, value: &str) -> Result<()> {\n    if value.is_empty() {\n        bail!(\"fleet {field} cannot be empty\");\n    }\n    if value.len() > MAX_FLEET_ID_BYTES || !value.chars().all(is_worker_token_char) {\n        bail!(\n            \"fleet {field} must be a simple ASCII token no longer than {MAX_FLEET_ID_BYTES} bytes\"\n        );\n    }\n    Ok(())\n}\n\nfn validate_fleet_name(field: &str, value: &str) -> Result<()> {\n    if value.trim().is_empty() {\n        bail!(\"fleet {field} cannot be empty\");\n    }\n    if value.len() > MAX_FLEET_NAME_BYTES || value.chars().any(char::is_control) {\n        bail!(\n            \"fleet {field} must be one printable line no longer than {MAX_FLEET_NAME_BYTES} bytes\"\n        );\n    }\n    Ok(())\n}\n\nfn validate_worker_profile(task_id: &str, worker: Option<&FleetTaskWorkerProfile>) -> Result<()> {\n    let Some(worker) = worker else {\n        return Ok(());\n    };\n    validate_worker_token(\n        task_id,\n        \"worker.agent_profile\",\n        worker.agent_profile.as_deref(),\n    )?;\n    validate_worker_token(task_id, \"worker.loadout\", worker.loadout.as_deref())?;\n    validate_worker_token(task_id, \"worker.model_class\", worker.model_class.as_deref())?;\n    validate_worker_model(task_id, worker.model.as_deref())?;","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/task_spec.rs#L147-L183","documentation":"validate_fleet_name bounds task and worker names to one printable line: at most MAX_FLEET_NAME_BYTES (256) bytes and no control characters (char::is_control catches newlines, tabs, and other control bytes). Long-form or multi-line content belongs in instructions/objective, not the name.","triggerScenarios":"name = \"line1\\nline2\" (embedded newline from pasting multi-line text), a name containing a tab, or a name longer than 256 bytes.","commonSituations":"Pasting a paragraph into the name field; templates inserting raw user text with line breaks; auto-generated names that concatenate many attributes until they exceed the limit.","solutions":["Collapse the name to a single printable line of 256 bytes or fewer","Move detail and multi-line content into instructions (or objective)","Sanitize templated names by stripping control characters at generation time"],"exampleFix":"// before\n{ \"id\": \"t1\", \"name\": \"Fix login\\nthen run tests\", \"instructions\": \"...\" }\n\n// after\n{ \"id\": \"t1\", \"name\": \"Fix login and run tests\", \"instructions\": \"Fix the login flow, then run the test suite.\" }","handlingStrategy":"validation","validationCode":"const MAX_FLEET_NAME_BYTES: usize = 256;\nfn is_fleet_name(s: &str) -> bool {\n    !s.trim().is_empty()\n        && s.len() <= MAX_FLEET_NAME_BYTES\n        && !s.chars().any(char::is_control)\n}","typeGuard":"function isOneLineName(name: string): boolean {\n  return name.trim().length > 0 && name.length <= 256 &&\n    !/[\\u0000-\\u001f]/.test(name);\n}","tryCatchPattern":"if let Err(err) = load_task_spec_document(&path) {\n    if err.to_string().contains(\"one printable line\") {\n        eprintln!(\"{path:?}: names must be a single line <=256 bytes; move detail to instructions\");\n    }\n    return Err(err);\n}","preventionTips":["Sanitize templated names: strip control characters and truncate to 256 bytes","Put multi-line content in instructions/objective, never in name","Validate pasted text before it lands in name fields"],"tags":["fleet","task-spec","name","validation","string-limits"],"backgroundTag":"invalid-name-format","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}