oneharness_core/
errors.rs1use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum OneharnessError {
11 #[error("no harness selected: pass --all or --harness <id>, or set `all`/`harnesses` in oneharness.toml (see `oneharness list`)")]
12 NoSelection,
13
14 #[error("unknown harness id `{id}`. valid ids: {valid}")]
15 UnknownHarness { id: String, valid: String },
16
17 #[error("no prompt provided: pass --prompt <text> or --prompt-file <path>")]
18 NoPrompt,
19
20 #[error("--prompt-file - (stdin) can be given only once, but it was passed {count} times")]
21 MultipleStdinPrompts { count: usize },
22
23 #[error("a batch run (more than one prompt) needs exactly one harness (a shared cache prefix is per harness/model), but {count} were selected: {selected}. Select one with --harness <id>")]
24 BatchMultipleHarnesses { count: usize, selected: String },
25
26 #[error("a batch run (more than one prompt) cannot be combined with --resume/--fork (those continue a single session with a single prompt)")]
27 BatchResume,
28
29 #[error("--resume needs exactly one harness (a session belongs to one harness), but {count} were selected: {selected}")]
30 ResumeMultipleHarnesses { count: usize, selected: String },
31
32 #[error("harness `{id}` does not support --resume. supported: {supported}")]
33 ResumeUnsupported { id: String, supported: String },
34
35 #[error("harness `{id}` does not support --fork (it resumes linearly, appending in place). supported: {supported}")]
36 ForkUnsupported { id: String, supported: String },
37
38 #[error("harness `{id}` does not support `--mode {mode}`. supported modes: {supported}")]
39 ModeUnsupported {
40 id: String,
41 mode: String,
42 supported: String,
43 },
44
45 #[error("could not read harness config `{path}`: {source}")]
46 HarnessConfigRead {
47 path: String,
48 #[source]
49 source: std::io::Error,
50 },
51
52 #[error("cannot sync into `{path}`: {message} (oneharness only rewrites files it can parse, so it never destroys content it does not understand)")]
53 HarnessConfigUnmergeable { path: String, message: String },
54
55 #[error("harness `{id}` has no hook mapping, so oneharness cannot install a hook into it")]
56 HookUnsupported { id: String },
57
58 #[error("harness `{id}` has no user-global hook location, so oneharness cannot install a global hook into it")]
59 HookGlobalUnsupported { id: String },
60
61 #[error("cannot resolve the user-global hook directory for `{id}`: {var} is not set")]
62 HookGlobalDirMissing { id: String, var: &'static str },
63
64 #[error("`oneharness sync --global` installs hooks only, but permission rules or `settings` are configured for `{id}` — those are project-scoped (sync them without --global, or remove them)")]
65 GlobalSyncOnlyHooks { id: String },
66
67 #[error(
68 "harness `{id}` has no pre-tool gate, so `oneharness gate {id}` cannot emit a verdict"
69 )]
70 GateUnsupported { id: String },
71
72 #[error("could not read mock rules file `{path}`: {source}")]
73 MockRulesFile {
74 path: String,
75 #[source]
76 source: std::io::Error,
77 },
78
79 #[error("invalid mock rules file `{path}`: {message}")]
80 MockRulesInvalid { path: String, message: String },
81
82 #[error("harness `{id}` cannot express the mock action `{action}`, so `oneharness mock {id}` refuses this ruleset (see `mock_rewrite`/`supports_mock_deny` in `oneharness list`)")]
83 MockActionUnsupported { id: String, action: &'static str },
84
85 #[error(
86 "harness `{id}` cannot take a one-shot mock hook (`--mock-rules`/`--spy-file`): {reason}"
87 )]
88 MockDeliveryUnsupported { id: String, reason: &'static str },
89
90 #[error("cannot embed `{path}` into a hook command: it contains whitespace (hook commands are tokenized on spaces by some harnesses; use space-free paths)")]
91 MockPathWhitespace { path: String },
92
93 #[error("could not wire the one-shot mock hook: {message}")]
94 MockSetup { message: String },
95
96 #[error("could not write harness config `{path}`: {source}")]
97 HarnessConfigWrite {
98 path: String,
99 #[source]
100 source: std::io::Error,
101 },
102
103 #[error("could not read prompt file `{path}`: {source}")]
104 PromptFile {
105 path: String,
106 #[source]
107 source: std::io::Error,
108 },
109
110 #[error("could not read schema file `{path}`: {source}")]
111 SchemaFile {
112 path: String,
113 #[source]
114 source: std::io::Error,
115 },
116
117 #[error("invalid --schema: {0}")]
118 Schema(String),
119
120 #[error("invalid --stream: {0}")]
121 StreamInvalid(String),
122
123 #[error("could not read config file `{path}`: {source}")]
124 ConfigRead {
125 path: String,
126 #[source]
127 source: std::io::Error,
128 },
129
130 #[error("invalid config file `{path}`: {message}")]
131 ConfigInvalid { path: String, message: String },
132
133 #[error("invalid environment-variable config override: {0}")]
134 EnvConfigInvalid(String),
135
136 #[error("invalid --bin override `{0}`: expected the form ID=PATH")]
137 BadBinOverride(String),
138
139 #[error("invalid --env `{0}`: expected the form KEY=VALUE")]
140 BadEnv(String),
141
142 #[error("could not write output to `{path}`: {source}")]
143 OutputDir {
144 path: String,
145 #[source]
146 source: std::io::Error,
147 },
148
149 #[error("failed to write JSON output: {0}")]
150 Serialize(#[from] serde_json::Error),
151}