How to Interpret Success and Failure in patent-disclosure-skill: Exit Codes and Output Prefixes

The patent-disclosure-skill signals operation results through process exit codes (0 for success, 1 for errors, 2 for fatal conditions) paired with stderr prefixes like DOCX: ok=1 that enable reliable automation in both shell and Python environments.

The patent-disclosure-skill repository provides command-line Python utilities for patent documentation processing, including DOCX generation, Mermaid diagram rendering, and patent crawling. Each tool implements a standardized dual-channel reporting mechanism that combines numeric exit codes with human-readable stderr prefixes. This design allows shell scripts to check $? while giving Python orchestrators access to structured metadata about failures.

The Dual-Channel Status System

The codebase employs two coordinated signaling mechanisms: process exit codes for shell-level compatibility, and prefixed status lines printed to stderr for programmatic parsing.

Process Exit Codes

The tools use sys.exit() to return specific numeric codes to the operating system:

  • 0 - Success. The operation completed without fatal errors.
  • 1 - Generic error or recoverable failure. The tool encountered a problem but the pipeline may continue.
  • 2 - Fatal condition. Essential input is missing or a critical error occurred that should halt the entire pipeline.

In skills/patent_search/tools/cnipa_epub_crawler.py, the crawler explicitly calls sys.exit(0) when new data is fetched successfully, sys.exit(1) when no new data is found (a harmless skip), and sys.exit(2) for network failures or critical errors.

Standard Error Prefixes

While exit codes provide binary success/failure signals, the tools write structured status lines to stderr using a consistent PREFIX: key=value format:

DOCX: ok=1
DOCX: ok=0 reason=missing_script
MERMAID: ok=0 exit=2 error=render_failed

The prefix identifies the tool (e.g., DOCX:, MERMAID:, Crawl:), followed by ok=1 for success or ok=0 for failure. Optional fields include exit=<n> (propagating the numeric code), reason=<msg> (classification), and error=<msg> (description).

Interpreting Exit Code Scenarios

Understanding the relationship between exit codes and prefixes enables robust error handling in automation scripts.

Normal Successful Execution

When a tool completes successfully, it prints a status line like:

DOCX: ok=1

And exits with code 0. Both signals agree, allowing simple shell checks with $? or parsed stderr inspection.

Recoverable Errors

For non-fatal issues such as missing optional files, the tool emits:

DOCX: ok=0 reason=missing_script

And exits with code 1. The prefix provides classification (reason=missing_script) while the exit code signals that the step failed but the pipeline might continue based on business logic.

Fatal Error Conditions

When essential inputs are absent, as seen in skills/patent_disclosure/tools/mermaid_render.py, the tool uses:

DOCX: ok=0 exit=2

With sys.exit(2) to indicate that continuation is unsafe. The combination of ok=0 and exit code 2 provides redundant signaling for critical failures.

Practical Implementation Examples

Checking Results in Bash Pipelines

Shell scripts can capture stderr to parse the status prefix while checking the exit code:

#!/usr/bin/env bash
set -euo pipefail

# Run the DOCX generation step

python -m skills.patent_disclosure.tools.md_to_docx ... 2>log.txt

# Extract the status line

status=$(grep -E '^DOCX:' log.txt)

if [[ $status == *"ok=1"* ]]; then
    echo "✅ DOCX created successfully"
else
    echo "❌ DOCX failed – $status"
    exit 1
fi

This pattern captures the structured output from stderr, checks for ok=1, and handles failures appropriately.

Parsing Status Lines in Python

Python orchestrators can subprocess the tools and parse the stderr output directly:

import subprocess, shlex, sys

def run_md_to_docx(src_md: str, out_docx: str) -> int:
    cmd = f"python -m skills.patent_disclosure.tools.md_to_docx {shlex.quote(src_md)} {shlex.quote(out_docx)}"
    proc = subprocess.run(cmd, shell=True, stderr=subprocess.PIPE, text=True)

    # Find the line that starts with "DOCX:"

    for line in proc.stderr.splitlines():
        if line.startswith("DOCX:"):
            parts = dict(item.split('=') for item in line.split()[1:] if '=' in item)
            ok = int(parts.get('ok', '0'))
            if ok == 1:
                return 0          # success

            else:
                print(f"Failed: {parts}", file=sys.stderr)
                return int(parts.get('exit', '1'))   # propagate the tool's exit code

    return 1   # fallback if no status line found

This function runs md_to_docx, parses the DOCX: prefixed line into a dictionary, and returns the appropriate exit code based on the ok field.

Handling Crawler Exit Codes

The CNIPA crawler demonstrates special-case exit codes for control flow:

python -m skills.patent_search.tools.cnipa_epub_crawler \
    --url https://example.cnipa.gov/xxxx

# Exit codes:

#   0 - crawl succeeded (new data fetched)

#   1 - nothing new, treat as harmless skip

#   2 - fatal error (network failure)

In the source, these sys.exit() calls are paired with printed status lines like print("CRAWL: ok=0"), allowing wrappers to distinguish between "no new data" (exit 1, but ok=0) and actual crashes.

Key Source Files

The following files implement these conventions across the repository:

These files collectively establish the standardized convention: a concise tool prefix followed by ok=<0|1> and optional key-value pairs printed to stderr, coordinated with appropriate sys.exit() calls.

Summary

  • Exit code 0 indicates successful completion, paired with ok=1 prefixes.
  • Exit code 1 signals generic or recoverable errors, typically with ok=0 and a reason= field.
  • Exit code 2 represents fatal conditions that should halt pipelines, often accompanied by exit=2 in the prefix.
  • Stderr prefixes follow the format PREFIX: ok=<status> [key=value...], enabling rich programmatic parsing beyond binary exit codes.
  • All tools in the repository write these prefixes to stderr, making the suite self-describing and automation-friendly.

Frequently Asked Questions

What exit code indicates success in patent-disclosure-skill tools?

Exit code 0 indicates success. This is returned by sys.exit(0) and paired with a stderr line containing ok=1 (for example, DOCX: ok=1). This convention holds across all utilities including md_to_docx.py and mermaid_render.py.

How do I check the status of a patent-disclosure-skill tool in a Bash script?

Capture stderr to a file or variable, then grep for the tool's prefix (e.g., ^DOCX:). Check for ok=1 to confirm success, or parse the reason= and exit= fields for failure details. You can also check $? for the exit code, though parsing the prefix provides more context about the failure type.

What is the difference between exit code 1 and exit code 2?

Exit code 1 indicates a generic or recoverable error (such as a missing optional file), allowing the pipeline to potentially continue. Exit code 2 signals a fatal condition (such as missing required input or network failure) where continuation is unsafe and the entire workflow should abort.

Why do the tools use both exit codes and stderr prefixes?

Shell scripts can only read exit codes through $?, providing a simple success/failure signal. Python orchestrators and advanced scripts can parse the stderr prefixes to access structured metadata like reason=missing_script or exit=2. This dual-channel approach maximizes compatibility across different automation environments while supporting granular error handling.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →