{"record":{"id":"05160b5a4da683be","repo":"Hmbown/CodeWhale","slug":"fleet-task-task-id-field-must-be-a-simple-toke","errorCode":null,"errorMessage":"fleet task {task_id} {field} must be a simple token, not a path or provider/model id","messagePattern":"fleet task (.+?) (.+?) must be a simple token, not a path or provider/model id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/task_spec.rs","lineNumber":196,"sourceCode":"        \"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())?;\n    Ok(())\n}\n\nfn validate_worker_token(task_id: &str, field: &str, value: Option<&str>) -> Result<()> {\n    let Some(value) = value else {\n        return Ok(());\n    };\n    let trimmed = value.trim();\n    if trimmed.is_empty() {\n        bail!(\"fleet task {task_id} {field} cannot be empty\");\n    }\n    if trimmed != value || !trimmed.chars().all(is_worker_token_char) {\n        bail!(\n            \"fleet task {task_id} {field} must be a simple token, not a path or provider/model id\"\n        );\n    }\n    Ok(())\n}\n\nfn is_worker_token_char(ch: char) -> bool {\n    ch.is_ascii_alphanumeric() || matches!(ch, '-' | '_' | '.')\n}\n\nfn validate_worker_model(task_id: &str, value: Option<&str>) -> Result<()> {\n    let Some(value) = value else {\n        return Ok(());\n    };\n    let trimmed = value.trim();\n    if trimmed.is_empty() {\n        bail!(\"fleet task {task_id} worker.model cannot be empty\");\n    }","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/task_spec.rs#L178-L214","documentation":"validate_worker_token requires worker.loadout and worker.model_class to be simple tokens: no leading/trailing whitespace and only ASCII alphanumerics plus '-', '_' and '.' (is_worker_token_char). The message calls out the two most common violations - file paths and provider/model ids - because both contain '/' or ':' and would be silently misresolved downstream.","triggerScenarios":"worker.loadout = \"./loadouts/standard.toml\" (a path), worker.model_class = \"openai/gpt-4o\" (a provider/model id), or a value with spaces like \"standard loadout\".","commonSituations":"Pointing loadout at a file instead of naming the loadout; copying a full model route into model_class; assuming these fields accept the same syntax as the profile loader's model field.","solutions":["Use the bare token name, e.g. worker.loadout = \"standard\" instead of a path","Put provider/model routes in worker.model, which accepts the richer id syntax - loadout and model_class take tokens only","Strip whitespace and path separators when generating these fields"],"exampleFix":"// before\n\"worker\": { \"loadout\": \"./loadouts/standard.toml\" }\n\n// after\n\"worker\": { \"loadout\": \"standard\" }","handlingStrategy":"validation","validationCode":"fn is_worker_token(s: &str) -> bool {\n    let t = s.trim();\n    !t.is_empty()\n        && t == s\n        && t.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.'))\n}","typeGuard":"function isWorkerToken(v: string): boolean {\n  return v.trim().length > 0 && v === v.trim() && /^[A-Za-z0-9._-]+$/.test(v);\n}","tryCatchPattern":"if let Err(err) = load_task_spec_document(&path) {\n    if err.to_string().contains(\"must be a simple token, not a path\") {\n        eprintln!(\"{path:?}: worker.loadout/model_class take bare tokens - no paths like ./x.toml, no provider/model ids\");\n    }\n    return Err(err);\n}","preventionTips":["Reference loadouts by name, never by file path","Put provider/model routes in worker.model; keep loadout/model_class as bare tokens","Reject '/' and ':' in these fields at the authoring boundary"],"tags":["fleet","task-spec","worker","loadout","identifier","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}