diff --git a/cli/planoai/config_generator.py b/cli/planoai/config_generator.py index c4e5831b..c167bef2 100644 --- a/cli/planoai/config_generator.py +++ b/cli/planoai/config_generator.py @@ -3,7 +3,7 @@ import os from planoai.utils import convert_legacy_listeners from jinja2 import Environment, FileSystemLoader import yaml -from jsonschema import validate +from jsonschema import validate, ValidationError from urllib.parse import urlparse from copy import deepcopy from planoai.consts import DEFAULT_OTEL_TRACING_GRPC_ENDPOINT @@ -507,11 +507,15 @@ def validate_prompt_config(plano_config_file, plano_config_schema_file): try: validate(config_yaml, config_schema_yaml) - except Exception as e: - print( - f"Error validating plano_config file: {plano_config_file}, schema file: {plano_config_schema_file}, error: {e}" + except ValidationError as e: + path = ( + " → ".join(str(p) for p in e.absolute_path) if e.absolute_path else "root" ) - raise e + raise ValidationError( + f"{e.message}\n Location: {path}\n Value: {e.instance}" + ) from None + except Exception as e: + raise if __name__ == "__main__": diff --git a/cli/planoai/native_runner.py b/cli/planoai/native_runner.py index 0e39a1fd..ed44e8ad 100644 --- a/cli/planoai/native_runner.py +++ b/cli/planoai/native_runner.py @@ -420,9 +420,16 @@ def native_validate_config(plano_config_file): with _temporary_env(overrides): from planoai.config_generator import validate_and_render_schema - # Suppress verbose print output from config_generator - with contextlib.redirect_stdout(io.StringIO()): - validate_and_render_schema() + # Suppress verbose print output from config_generator but capture errors + captured = io.StringIO() + try: + with contextlib.redirect_stdout(captured): + validate_and_render_schema() + except SystemExit: + # validate_and_render_schema calls exit(1) on failure after + # printing to stdout; re-raise so the caller gets a useful message. + output = captured.getvalue().strip() + raise Exception(output) if output else Exception("Config validation failed") def native_logs(debug=False, follow=False):