Add errors to TomlFile and Project for TOML parse failure tracking#7130
Add errors to TomlFile and Project for TOML parse failure tracking#7130ryancbahan wants to merge 4 commits intoryan/validate-json-contractfrom
Conversation
|
We detected some changes at Caution DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release. |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lidate --json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4f4200b to
50263be
Compare
14a803b to
aacac17
Compare
…lidate --json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lidate --json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/public/node/toml/toml-file.d.ts import { JsonMapType } from './codec.js';
/**
- * Thrown when a TOML file does not exist at the expected path.
+ * An error on a TOML file — missing or malformed.
+ * Extends Error so it can be thrown. Carries path and a clean message suitable for JSON output.
*/
-export declare class TomlFileNotFoundError extends Error {
+export declare class TomlFileError extends Error {
readonly path: string;
- constructor(path: string);
+ constructor(path: string, message: string);
}
/**
- * Thrown when a TOML file cannot be parsed. Includes the file path for context.
- */
-export declare class TomlParseError extends Error {
- readonly path: string;
- constructor(path: string, cause: Error);
-}
-/**
* General-purpose TOML file abstraction.
*
* Provides a unified interface for reading, patching, removing keys from, and replacing
* the content of TOML files on disk.
*
* - `read` populates content from disk
* - `patch` does surgical WASM-based edits (preserves comments and formatting)
* - `remove` deletes a key by dotted path (preserves comments and formatting)
* - `replace` does a full re-serialization (comments and formatting are NOT preserved).
* - `transformRaw` applies a function to the raw TOML string on disk.
*/
export declare class TomlFile {
/**
- * Read and parse a TOML file from disk. Throws if the file doesn't exist or contains invalid TOML.
- * Parse errors are wrapped in {@link TomlParseError} with the file path for context.
+ * Read and parse a TOML file from disk. Throws {@link TomlFileError} if the file
+ * doesn't exist or contains invalid TOML.
*
* @param path - Absolute path to the TOML file.
* @returns A TomlFile instance with parsed content.
*/
static read(path: string): Promise<TomlFile>;
readonly path: string;
content: JsonMapType;
+ readonly errors: TomlFileError[];
constructor(path: string, content: JsonMapType);
/**
* Surgically patch values in the TOML file, preserving comments and formatting.
*
* Accepts a nested object whose leaf values are set in the TOML. Intermediate tables are
* created automatically. Setting a leaf to `undefined` removes it (use `remove()` for a
* clearer API when deleting keys).
*
* @example
* ```ts
* await file.patch({build: {dev_store_url: 'my-store.myshopify.com'}})
* await file.patch({application_url: 'https://example.com', auth: {redirect_urls: ['...']}})
* ```
*/
patch(changes: {
[key: string]: unknown;
}): Promise<void>;
/**
* Remove a key from the TOML file by dotted path, preserving comments and formatting.
*
* @param keyPath - Dotted key path to remove (e.g. 'build.include_config_on_deploy').
* @example
* ```ts
* await file.remove('build.include_config_on_deploy')
* ```
*/
remove(keyPath: string): Promise<void>;
/**
* Replace the entire file content. The file is fully re-serialized — comments and formatting
* are NOT preserved.
*
* @param content - The new content to write.
* @example
* ```ts
* await file.replace({client_id: 'abc', name: 'My App'})
* ```
*/
replace(content: JsonMapType): Promise<void>;
/**
* Transform the raw TOML string on disk. Reads the file, applies the transform function
* to the raw text, writes back, and re-parses to keep `content` in sync.
*
* Use this for text-level operations that can't be expressed as structured edits —
* e.g. Injecting comments or positional insertion of keys in arrays-of-tables.
* Subsequent `patch()` calls will preserve any comments added this way.
*
* @param transform - A function that receives the raw TOML string and returns the modified string.
* @example
* ```ts
* await file.transformRaw((raw) => `# Header comment\n${raw}`)
* ```
*/
transformRaw(transform: (raw: string) => string): Promise<void>;
private decode;
}
|

What
Unify TOML error types, add
errorstoTomlFileandProject, and surface TOML parse failures inapp config validate --json.How
Unified error type:
TomlFileNotFoundErrorandTomlParseErrorreplaced with singleTomlFileErrorclass. Parse errors produce clean one-line messages ("Invalid boolean, expected true or false at row 6, col 13") instead of multi-line ASCII art.TomlFile.errors: New field onTomlFile.read()still throws. Callers that catch create aTomlFilewith the path and error populated — the file exists in the model even when malformed.Project.errors: Aggregated from all discovery passes. Malformed files are included inappConfigFiles/extensionConfigFiles/webConfigFiles(with errors and empty content) instead of silently dropped.Validate command: Checks
project.errorsbefore attempting to link. Reports TOML parse errors as{valid: false, issues: [{file, message}]}in JSON mode.Depends on #7128, #7126.
Tophatting
valid config
Screen Recording 2026-03-30 at 4.20.35 PM.mov (uploaded via Graphite)
invalid config -- shopify domain
Screen Recording 2026-03-30 at 4.21.52 PM.mov (uploaded via Graphite)
invalid config -- invalid toml syntax
Screen Recording 2026-03-30 at 4.22.47 PM.mov (uploaded via Graphite)