helm_schema/error.rs
1use std::path::PathBuf;
2
3/// Errors produced while loading charts, analyzing templates, and emitting schemas.
4#[derive(Debug, thiserror::Error)]
5pub enum CliError {
6 /// Virtual-filesystem operation failed.
7 #[error("vfs error: {0}")]
8 Vfs(#[from] vfs::VfsError),
9
10 /// Operating-system I/O operation failed.
11 #[error("io error: {0}")]
12 Io(#[from] std::io::Error),
13
14 /// YAML input could not be decoded.
15 #[error("yaml error: {0}")]
16 Yaml(#[from] serde_yaml::Error),
17
18 /// Values declarations use keys whose spelling Helm normalizes ambiguously.
19 #[error(
20 "unquoted YAML 1.1 Boolean-alias keys are not supported in chart declarations:\n{details}"
21 )]
22 YamlBooleanAliasKeys {
23 /// Deterministically ordered file locations and source spellings.
24 details: String,
25 },
26
27 /// A values declaration could not be structurally inspected for key style.
28 #[error("failed to inspect YAML Boolean-alias keys in {path}: {message}")]
29 YamlBooleanAliasScan {
30 /// Values declaration being inspected.
31 path: String,
32 /// YAML parser failure.
33 message: String,
34 },
35
36 /// Multiple dependency declarations target the same values root.
37 #[error(
38 "duplicate dependency values keys in {path}:\n{details}\neach dependency must own a unique .Values root"
39 )]
40 DuplicateDependencyValuesKeys {
41 /// Manifest containing the duplicate declarations.
42 path: String,
43 /// Deterministically ordered values keys and their declarations.
44 details: String,
45 },
46
47 /// Multiple vendored entries have the same internal chart name.
48 #[error(
49 "duplicate installed dependency names in {path}:\n{details}\nHelm's installed-entry association for duplicate internal names is nondeterministic"
50 )]
51 DuplicateInstalledDependencyNames {
52 /// Vendored charts directory containing the duplicate entries.
53 path: String,
54 /// Deterministically ordered internal names and entry paths.
55 details: String,
56 },
57
58 /// JSON input or output could not be decoded or encoded.
59 #[error("json error: {0}")]
60 Json(#[from] serde_json::Error),
61
62 /// A caller override is not a JSON Schema document root.
63 #[error("override schema root in {path} must be an object or boolean, found {kind}")]
64 InvalidOverrideRoot {
65 /// Override file carrying the invalid root.
66 path: PathBuf,
67 /// JSON kind found at the document root.
68 kind: &'static str,
69 },
70
71 /// A final output document is not a JSON Schema root.
72 #[error("final schema root must be an object or boolean, found {kind}")]
73 InvalidFinalSchemaRoot {
74 /// JSON kind found at the document root.
75 kind: &'static str,
76 },
77
78 /// Helm template source could not be parsed.
79 #[error("template parse error: {0}")]
80 TemplateParse(#[from] helm_schema_ast::ParseError),
81
82 /// Chart discovery found no analyzable charts.
83 #[error("no charts discovered")]
84 NoChartsDiscovered,
85
86 /// A discovered subchart path has no usable chart name.
87 #[error("subchart name missing for {path}")]
88 SubchartNameMissing {
89 /// Path of the unnamed subchart.
90 path: String,
91 },
92
93 /// An archive does not contain a chart manifest.
94 #[error("no Chart.yaml found in archive {archive}")]
95 NoChartYamlInArchive {
96 /// Path or identifier of the archive.
97 archive: String,
98 },
99
100 /// The output directory could not be created.
101 #[error("failed to create output directory {path}")]
102 CreateOutputDir {
103 /// Directory creation target.
104 path: PathBuf,
105 /// Underlying filesystem failure.
106 #[source]
107 source: std::io::Error,
108 },
109
110 /// A generated schema could not be written.
111 #[error("failed to write output {path}")]
112 WriteOutput {
113 /// Output file that could not be written.
114 path: PathBuf,
115 /// Underlying filesystem failure.
116 #[source]
117 source: std::io::Error,
118 },
119
120 /// Wraps any failure surfaced by the `jsonschema` / `referencing`
121 /// full-inlining pass: file-not-found, JSON parse error, malformed
122 /// URI, pointer-to-nowhere, missing anchor, etc. The wrapped variant
123 /// carries the structured cause so callers can pattern-match on the
124 /// underlying problem (e.g. `Unretrievable { uri, source }` vs
125 /// `PointerToNowhere { pointer }`) rather than parsing a string.
126 #[error("$ref resolution failed: {0}")]
127 Referencing(#[from] jsonschema::ReferencingError),
128
129 /// A self-contained schema could not be produced from external references.
130 #[error("$ref bundling failed: {0}")]
131 RefBundling(String),
132
133 /// A local filesystem path cannot be represented as a file URI.
134 #[error("filesystem path cannot be represented as a file URI: {path}")]
135 InvalidFileUriPath {
136 /// Filesystem path that could not be encoded.
137 path: PathBuf,
138 },
139
140 /// A file URI cannot be represented as a local filesystem path.
141 #[error("file URI cannot be represented as a local filesystem path: {uri}")]
142 InvalidFileUri {
143 /// File URI that could not be decoded.
144 uri: String,
145 },
146
147 /// One loaded document exceeded the configured byte budget.
148 #[error("load budget exceeded for {subject} (limit {limit_bytes} bytes)")]
149 LoadBudgetExceeded {
150 /// Document or archive member being loaded.
151 subject: String,
152 /// Maximum permitted byte count.
153 limit_bytes: usize,
154 },
155
156 /// An archive or directory exceeded the configured entry budget.
157 #[error("load budget exceeded for {subject} (limit {limit_entries} entries)")]
158 LoadEntryBudgetExceeded {
159 /// Archive or directory being enumerated.
160 subject: String,
161 /// Maximum permitted entry count.
162 limit_entries: usize,
163 },
164
165 /// An archive member would escape its extraction root.
166 #[error("unsafe archive entry path {entry_path} in {archive}")]
167 UnsafeArchiveEntryPath {
168 /// Archive containing the unsafe member.
169 archive: String,
170 /// Untrusted member path rejected by validation.
171 entry_path: String,
172 },
173
174 /// Mutually-exclusive CLI flags or otherwise-invalid combination
175 /// detected after `clap` parsing succeeded.
176 #[error("invalid CLI options: {0}")]
177 CliValidation(String),
178
179 /// An emission selection resolves to a contradictory knob matrix.
180 #[error("invalid emission policy: {0}")]
181 InvalidEmissionPolicy(#[from] helm_schema_gen::InvalidEmissionPolicy),
182
183 /// An explicit config path could not be read.
184 #[error("failed to read config {path}: {source}")]
185 ConfigRead {
186 /// Config file path.
187 path: PathBuf,
188 /// Underlying filesystem failure.
189 #[source]
190 source: std::io::Error,
191 },
192
193 /// A config document is malformed or contains unknown fields.
194 #[error("invalid config {path}: {source}")]
195 InvalidConfig {
196 /// Config file path or packaged-chart member label.
197 path: String,
198 /// YAML decoding failure.
199 #[source]
200 source: serde_yaml::Error,
201 },
202
203 /// A config document uses a version this binary cannot honor exactly.
204 #[error(
205 "unsupported config version {found} in {path}; supported range is {supported_min}..={supported_max}; update the config or the helm-schema binary"
206 )]
207 UnsupportedConfigVersion {
208 /// Config file path.
209 path: PathBuf,
210 /// Version requested by the config.
211 found: u64,
212 /// Oldest config version honored by this binary.
213 supported_min: u64,
214 /// Newest config version honored by this binary.
215 supported_max: u64,
216 },
217}
218
219/// Result returned by the schema engine's public operations.
220pub type EngineResult<T> = std::result::Result<T, CliError>;