How OfficeCLI Handles Structured Error Codes and Suggestions for Self-Healing Workflows
OfficeCLI uses a machine-readable error model centered on CliException that emits JSON envelopes containing error codes, human-readable suggestions, and help commands, enabling AI agents and scripts to implement automated remediation workflows.
OfficeCLI (iOfficeAI/OfficeCLI) provides a robust command-line interface for office automation that leverages structured error codes and suggestions for self-healing workflows. Instead of emitting plain text errors, the framework encapsulates failure metadata in machine-readable payloads, allowing downstream tools to parse, categorize, and automatically resolve issues without human intervention.
The CliException Class: Foundation of Structured Errors
Structured Payload Properties
In src/officecli/Core/CliException.cs, the CliException class defines a structured payload with four key properties:
- Code: A machine-readable identifier (e.g.,
not_found,invalid_value,unsupported_property) - Suggestion: A human-readable fix recommendation (e.g., "Did you mean 'fontSize'?")
- Help: An optional command to retrieve documentation (e.g.,
officecli help set) - ValidValues: An array of acceptable values when rejecting invalid choices
Throwing Structured Exceptions
Handlers throughout the codebase throw CliException with populated metadata to communicate specific failure modes:
// Inside a Word handler (src/officecli/Handlers/WordHandler.Set.cs)
if (!AllowedProperties.Contains(propName))
{
throw new CliException($"Property '{propName}' is not supported")
{
Code = "unsupported_property",
Suggestion = $"Did you mean '{GetClosestMatch(propName)}'?",
Help = "officecli help set"
};
}
JSON Envelope Format for Machine-Readable Output
OutputFormatter Serialization
The OutputFormatter class in src/officecli/Core/OutputFormatter.cs serializes all exceptions into a deterministic JSON schema. This ensures that both successes and failures follow the same envelope structure, making the output predictable for parsers.
Guaranteed Schema Contracts
When OutputFormatter processes a CliException, it generates a JSON object containing error, code, suggestion, help, and validValues fields. If an exception lacks a code, the formatter defaults to internal_error, preventing schema fragmentation and ensuring downstream tools always receive a parseable response.
{
"error": "Property 'fontcolr' is not recognized",
"code": "unsupported_property",
"suggestion": "Did you mean 'fontColor'?",
"help": "officecli help set",
"validValues": null
}
ResidentServer Error Handling Pipeline
Exception Catching and Wrapping
In src/officecli/ResidentServer.cs, the server architecture catches CliException instances from the core engine and wraps them in the JSON envelope before writing to the client pipe. This ensures that resident mode callers always receive well-formed error responses suitable for programmatic parsing, regardless of where the failure occurs in the execution stack.
Warning Objects with Error Codes
Even non-fatal conditions carry structured codes. According to the source in ResidentServer.cs (lines 982-1004), warning objects include fields like unrecognized_latex_command and validation_error, allowing callers to decide whether to retry operations or adjust inputs without terminating the workflow.
Implementing Self-Healing Workflows
Automated Remediation Patterns
Because the error payload contains suggestions and validValues, automation scripts can implement decision trees. For invalid_value errors that include validValues, agents can automatically select the first valid alternative and retry. For unsupported_property errors, they can apply the suggested correction and re-execute.
AI Agent Integration
AI-driven assistants can implement self-healing loops by parsing the JSON response, applying the suggestion, and re-executing the command. This pattern eliminates manual intervention for common typos and configuration errors.
import json, subprocess, sys
result = subprocess.run(
["officecli", "set", "fontcolr=red"],
capture_output=True, text=True
)
payload = json.loads(result.stdout)
if "error" in payload:
print(f"Error [{payload['code']}]: {payload['error']}")
if payload.get("suggestion"):
print("Suggestion:", payload['suggestion'])
if payload.get("help"):
subprocess.run(payload["help"].split())
sys.exit(1)
Self-Healing Pseudo-Code
The following pattern demonstrates how AI agents utilize the structured error model to create autonomous remediation loops:
run command
if response.code == "invalid_value" and response.validValues:
pick first valid value -> newCommand
run newCommand
elif response.suggestion:
apply suggestion -> newCommand
run newCommand
else:
abort and present help
Plugin Ecosystem Consistency
FormatHandlerProxy Standardization
The FormatHandlerProxy class in src/officecli/Core/Plugins/FormatHandlerProxy.cs ensures plugins adhere to the core error contract. When plugins throw exceptions, the proxy maps them to standardized codes like unsupported_command or invalid_value, maintaining consistency across the ecosystem.
// From FormatHandlerProxy.cs
catch (CliException ex) when (ex.Code == "unsupported_command")
{
// Convert plugin error into core-compatible JSON envelope
return ErrorJson(null, -32601, ex.Message);
}
Cross-Protocol Error Contracts
Plugins interacting through the plugin-protocol.md specification must return errors using the CliException schema. This requirement ensures that Node SDKs, Python SDKs, and custom format handlers all emit the same deterministic error structure, enabling universal self-healing capabilities across language boundaries.
Summary
CliExceptioninsrc/officecli/Core/CliException.csprovides the foundational structured payload withCode,Suggestion,Help, andValidValuesproperties.OutputFormatterinsrc/officecli/Core/OutputFormatter.csguarantees all output follows a JSON schema that includes machine-readable error codes and human-readable suggestions.ResidentServerinsrc/officecli/ResidentServer.cswraps exceptions in JSON envelopes and supports warning objects with codes for non-fatal conditions.- Self-healing workflows leverage the
suggestionandvalidValuesfields to enable automated remediation by AI agents and CI pipelines. FormatHandlerProxyenforces error code consistency across plugins, ensuring theunsupported_commandandinvalid_valueschemas remain uniform regardless of the implementation language.
Frequently Asked Questions
What is the difference between a CliException and a standard error in OfficeCLI?
A CliException is a specialized exception type defined in src/officecli/Core/CliException.cs that carries a structured payload including Code, Suggestion, Help, and ValidValues. Standard errors lack this metadata and are converted to internal_error by the OutputFormatter, whereas CliException instances provide actionable data for self-healing workflows.
How can I parse OfficeCLI errors in a Python script to implement self-healing?
Capture the JSON output from OfficeCLI commands, load it with json.loads(), and inspect the code and suggestion fields. If the code is invalid_value and validValues are present, programmatically select a valid value and retry the command. If a suggestion is provided, apply the correction before re-execution.
What error codes are available in the OfficeCLI structured error model?
Common codes include not_found, invalid_value, unsupported_property, unsupported_command, unrecognized_latex_command, and validation_error. The OutputFormatter defaults to internal_error for unclassified exceptions, ensuring the schema always contains a code field.
How do plugins maintain error code consistency with the core OfficeCLI engine?
Plugins use the FormatHandlerProxy class in src/officecli/Core/Plugins/FormatHandlerProxy.cs to translate plugin-specific failures into the shared CliException schema. This proxy ensures that errors like unsupported_command follow the same JSON envelope structure as core engine errors, maintaining consistency across the ecosystem.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →