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

> Master patent-disclosure-skill results with exit codes (0 success, 1 error, 2 fatal) and stderr prefixes. Automate shell and Python workflows reliably. Learn to interpret success and failure.

- Repository: [handsomestWei/patent-disclosure-skill](https://github.com/handsomestWei/patent-disclosure-skill)
- Tags: how-to-guide
- Published: 2026-09-06

---

**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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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:

```text
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:

```text
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:

```text
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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/skills/patent_disclosure/tools/mermaid_render.py), the tool uses:

```text
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:

```bash
#!/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:

```python
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:

```bash
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:

- **[`skills/patent_disclosure/tools/md_to_docx.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/skills/patent_disclosure/tools/md_to_docx.py)** - Emits `DOCX: ok=1` on success and `DOCX: ok=0 reason=<msg>` on failure during Markdown-to-DOCX conversion.
- **[`skills/patent_disclosure/tools/mermaid_render.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/skills/patent_disclosure/tools/mermaid_render.py)** - Prints `DOCX: ok=0 exit=<code>` for Mermaid diagram rendering failures.
- **[`skills/patent_disclosure/tools/latex_delimiters.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/skills/patent_disclosure/tools/latex_delimiters.py)** - Uses the `DOCX:` prefix with `reason=latex_delim` for LaTeX delimiter errors.
- **[`skills/patent_search/tools/cnipa_epub_crawler.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/skills/patent_search/tools/cnipa_epub_crawler.py)** - Demonstrates exit code 0/1/2 usage with `Crawl:` prefixed status lines.
- **[`skills/patent_oa/tools/md_to_docx.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/skills/patent_oa/tools/md_to_docx.py)** - Implements `DOCX: ok=1` success signaling for Open-Access patent processing.

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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/md_to_docx.py) and [`mermaid_render.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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.