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